aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Duggan <ad@aduggan.com>2014-09-30 13:48:41 -0700
committerAndrew Duggan <ad@aduggan.com>2014-09-30 13:48:41 -0700
commitab33df52cf2543f80a799701ba8a380d32d7a40e (patch)
treee034852ed90056bb669ffd84ae8c3911799b5df7
parent28b8622623837b6cf065ad82570251e1d2991874 (diff)
parentc534360872fbaeed9b9927cfbfa67b4fbe45234d (diff)
downloadplatform_external_rmi4utils-ab33df52cf2543f80a799701ba8a380d32d7a40e.tar.gz
platform_external_rmi4utils-ab33df52cf2543f80a799701ba8a380d32d7a40e.tar.bz2
platform_external_rmi4utils-ab33df52cf2543f80a799701ba8a380d32d7a40e.zip
Merge pull request #6 from synasnoguchi/master
Add f54 test
-rw-r--r--Makefile2
-rw-r--r--f54test/Android.mk10
-rw-r--r--f54test/Makefile22
-rw-r--r--f54test/display.cpp129
-rw-r--r--f54test/display.h55
-rw-r--r--f54test/f54test.cpp1568
-rw-r--r--f54test/f54test.h709
-rw-r--r--f54test/main.cpp178
-rw-r--r--f54test/testutil.cpp70
-rw-r--r--f54test/testutil.h46
-rw-r--r--rmi4update/main.cpp16
-rw-r--r--rmi4update/rmi4update.cpp4
-rw-r--r--rmi4update/rmi4update.h2
-rw-r--r--rmidevice/rmidevice.cpp15
-rw-r--r--rmidevice/rmidevice.h6
-rw-r--r--rmidevice/rmifunction.cpp25
-rw-r--r--rmidevice/rmifunction.h6
17 files changed, 2844 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 4ad5ad3..48dce6a 100644
--- a/Makefile
+++ b/Makefile
@@ -5,11 +5,13 @@ all:
$(MAKE) -C rmidevice all
$(MAKE) -C rmi4update all
$(MAKE) -C rmihidtool all
+ $(MAKE) -C f54test all
clean:
$(MAKE) -C rmidevice clean
$(MAKE) -C rmi4update clean
$(MAKE) -C rmihidtool clean
+ $(MAKE) -C f54test clean
android:
ndk-build NDK_APPLICATION_MK=Application.mk
diff --git a/f54test/Android.mk b/f54test/Android.mk
new file mode 100644
index 0000000..58aa67b
--- /dev/null
+++ b/f54test/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := f54test
+LOCAL_C_INCLUDES := rmidevice
+LOCAL_SRC_FILES := main.cpp f54test.cpp testutil.cpp display.cpp
+LOCAL_CPPFLAGS := -Wall
+LOCAL_STATIC_LIBRARIES := rmidevice
+
+include $(BUILD_EXECUTABLE) \ No newline at end of file
diff --git a/f54test/Makefile b/f54test/Makefile
new file mode 100644
index 0000000..e0f1b64
--- /dev/null
+++ b/f54test/Makefile
@@ -0,0 +1,22 @@
+CXX ?= g++
+CPPFLAGS += -I../include -I./include -I../rmidevice
+CXXFLAGS += -Wall
+LDFLAGS += -L.
+LIBS = -lrmidevice -lrt
+LIBDIR = ../rmidevice
+LIBNAME = librmidevice.a
+F54TESTSRC = main.cpp f54test.cpp testutil.cpp display.cpp
+F54TESTOBJ = $(F54TESTSRC:.cpp=.o)
+PROGNAME = f54test
+STATIC_BUILD ?= y
+ifeq ($(STATIC_BUILD),y)
+LDFLAGS += -static
+endif
+
+all: $(PROGNAME)
+
+$(PROGNAME): $(F54TESTOBJ)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) $(F54TESTOBJ) -L$(LIBDIR) $(LIBS) -o $(PROGNAME)
+
+clean:
+ rm -f $(F54TESTOBJ) $(PROGNAME)
diff --git a/f54test/display.cpp b/f54test/display.cpp
new file mode 100644
index 0000000..00c4bfa
--- /dev/null
+++ b/f54test/display.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "display.h"
+
+#define ESC 0x1B
+
+// default display
+void Display::Output(const char * buf)
+{
+ printf("%s", buf);
+}
+
+// ansi console
+AnsiConsole::AnsiConsole() : Display()
+{
+ m_buf = NULL;
+ GetWindowSize();
+ m_curX = 0;
+ m_curY = 0;
+ m_maxCurX = 0;
+ m_maxCurY = 0;
+}
+
+AnsiConsole::~AnsiConsole()
+{
+ delete [] m_buf;
+}
+
+void AnsiConsole::GetWindowSize()
+{
+ struct winsize winsz;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsz);
+ if (m_numRows != winsz.ws_row || m_numCols != winsz.ws_col)
+ {
+ m_numRows = winsz.ws_row;
+ m_numCols = winsz.ws_col;
+ if (m_buf != NULL)
+ {
+ delete [] m_buf;
+ }
+ m_buf = new char[m_numRows * m_numCols];
+
+ Clear();
+ }
+}
+
+void AnsiConsole::Output(const char * buf)
+{
+ char * p;
+
+ while (m_curY < m_numRows &&
+ m_numCols * m_curY + m_curX < m_numRows * m_numCols)
+ {
+ p = &(m_buf[m_numCols * m_curY + m_curX]);
+
+ if (*buf == '\0')
+ {
+ break;
+ }
+ else if (*buf == '\n')
+ {
+ memset(p, ' ', m_numCols - m_curX);
+ m_curX = 0;
+ m_curY++;
+ }
+ else if (m_curX < m_numCols)
+ {
+ *p = *buf;
+ m_curX++;
+ }
+ buf++;
+
+ if (m_maxCurX < m_curX) m_maxCurX = m_curX;
+ if (m_maxCurY < m_curY) m_maxCurY = m_curY;
+ }
+}
+
+void AnsiConsole::Clear()
+{
+ printf("%c[2J", ESC);
+}
+
+void AnsiConsole::Reflesh()
+{
+ int i;
+ int j;
+ char * p;
+
+ printf("%c[%d;%dH", ESC, 0, 0);
+
+ for (j = 0; j < m_maxCurY; j++)
+ {
+ p = &(m_buf[m_numCols * j]);
+
+ for (i = 0; i < m_maxCurX; i++)
+ {
+ putc(*p, stdout);
+ p++;
+ }
+
+ putc('\n', stdout);
+ }
+
+ GetWindowSize();
+ m_curX = 0;
+ m_curY = 0;
+ m_maxCurX = 0;
+ m_maxCurY = 0;
+}
diff --git a/f54test/display.h b/f54test/display.h
new file mode 100644
index 0000000..f0629ad
--- /dev/null
+++ b/f54test/display.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+class Display
+{
+public:
+ Display() {}
+ virtual ~Display() {}
+
+ virtual void Clear() {};
+ virtual void Reflesh() {};
+ virtual void Output(const char * buf);
+};
+
+class AnsiConsole : public Display
+{
+public:
+ AnsiConsole();
+ virtual ~AnsiConsole();
+
+ virtual void Clear();
+ virtual void Reflesh();
+ virtual void Output(const char * buf);
+
+private:
+ void GetWindowSize();
+
+protected:
+ int m_numCols;
+ int m_numRows;
+ int m_curX;
+ int m_curY;
+ int m_maxCurX;
+ int m_maxCurY;
+ char * m_buf;
+};
+
+#endif // _DISPLAY_H_
diff --git a/f54test/f54test.cpp b/f54test/f54test.cpp
new file mode 100644
index 0000000..7c43574
--- /dev/null
+++ b/f54test/f54test.cpp
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <alloca.h>
+#include <time.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <math.h>
+
+#include "testutil.h"
+#include "f54test.h"
+#include "rmidevice.h"
+#include "display.h"
+
+/* Most recent device status event */
+#define RMI_F01_STATUS_CODE(status) ((status) & 0x0f)
+/* Indicates that flash programming is enabled (bootloader mode). */
+#define RMI_F01_STATUS_BOOTLOADER(status) (!!((status) & 0x40))
+
+/*
+ * Sleep mode controls power management on the device and affects all
+ * functions of the device.
+ */
+#define RMI_F01_CTRL0_SLEEP_MODE_MASK 0x03
+
+#define RMI_SLEEP_MODE_NORMAL 0x00
+#define RMI_SLEEP_MODE_SENSOR_SLEEP 0x01
+#define RMI_SLEEP_MODE_RESERVED0 0x02
+#define RMI_SLEEP_MODE_RESERVED1 0x03
+
+/*
+ * This bit disables whatever sleep mode may be selected by the sleep_mode
+ * field and forces the device to run at full power without sleeping.
+ */
+#define RMI_F01_CRTL0_NOSLEEP_BIT (1 << 2)
+
+F54Test::~F54Test()
+{
+ if (m_txAssignment != NULL) delete [] m_txAssignment;
+ if (m_rxAssignment != NULL) delete [] m_rxAssignment;
+}
+
+int F54Test::Prepare(f54_report_types reportType)
+{
+ int retval;
+ unsigned char data;
+
+ retval = FindTestFunctions();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = m_device.QueryBasicProperties();
+ if (retval < 0)
+ return TEST_FAIL_QUERY_BASIC_PROPERTIES;
+
+ retval = ReadF54Queries();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = SetupF54Controls();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = ReadF55Queries();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = SetF54ReportType(reportType);
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = SetF54Interrupt();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ data = (unsigned char)m_reportType;
+ retval = m_device.Write(m_f54.GetDataBase(), &data, 1);
+ if (retval < 0)
+ return retval;
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::Run()
+{
+ int retval;
+ unsigned char command;
+
+ command = (unsigned char)COMMAND_GET_REPORT;
+ retval = DoF54Command(command);
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = ReadF54Report();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ retval = ShowF54Report();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::SetF54ReportType(f54_report_types report_type)
+{
+ switch (report_type) {
+ case F54_8BIT_IMAGE:
+ case F54_16BIT_IMAGE:
+ case F54_RAW_16BIT_IMAGE:
+ case F54_HIGH_RESISTANCE:
+ case F54_TX_TO_TX_SHORTS:
+ case F54_RX_TO_RX_SHORTS_1:
+ case F54_TRUE_BASELINE:
+ case F54_FULL_RAW_CAP_MIN_MAX:
+ case F54_RX_OPENS_1:
+ case F54_TX_OPENS:
+ case F54_TX_TO_GND_SHORTS:
+ case F54_RX_TO_RX_SHORTS_2:
+ case F54_RX_OPENS_2:
+ case F54_FULL_RAW_CAP:
+ case F54_FULL_RAW_CAP_NO_RX_COUPLING:
+ case F54_SENSOR_SPEED:
+ case F54_ADC_RANGE:
+ case F54_TRX_OPENS:
+ case F54_TRX_TO_GND_SHORTS:
+ case F54_TRX_SHORTS:
+ case F54_ABS_RAW_CAP:
+ case F54_ABS_DELTA_CAP:
+ m_reportType = report_type;
+ return SetF54ReportSize(report_type);
+ default:
+ m_reportType = INVALID_REPORT_TYPE;
+ m_reportSize = 0;
+ return TEST_FAIL_INVALID_PARAMETER;
+ }
+}
+
+int F54Test::SetF54ReportSize(f54_report_types report_type)
+{
+ int retval;
+ unsigned char tx = m_txAssigned;
+ unsigned char rx = m_rxAssigned;
+
+ switch (report_type) {
+ case F54_8BIT_IMAGE:
+ m_reportSize = tx * rx;
+ break;
+ case F54_16BIT_IMAGE:
+ case F54_RAW_16BIT_IMAGE:
+ case F54_TRUE_BASELINE:
+ case F54_FULL_RAW_CAP:
+ case F54_FULL_RAW_CAP_NO_RX_COUPLING:
+ case F54_SENSOR_SPEED:
+ m_reportSize = 2 * tx * rx;
+ break;
+ case F54_HIGH_RESISTANCE:
+ m_reportSize = HIGH_RESISTANCE_DATA_SIZE;
+ break;
+ case F54_TX_TO_TX_SHORTS:
+ case F54_TX_OPENS:
+ case F54_TX_TO_GND_SHORTS:
+ m_reportSize = (tx + 7) / 8;
+ break;
+ case F54_RX_TO_RX_SHORTS_1:
+ case F54_RX_OPENS_1:
+ if (rx < tx)
+ m_reportSize = 2 * rx * rx;
+ else
+ m_reportSize = 2 * tx * rx;
+ break;
+ case F54_FULL_RAW_CAP_MIN_MAX:
+ m_reportSize = FULL_RAW_CAP_MIN_MAX_DATA_SIZE;
+ break;
+ case F54_RX_TO_RX_SHORTS_2:
+ case F54_RX_OPENS_2:
+ if (rx <= tx)
+ m_reportSize = 0;
+ else
+ m_reportSize = 2 * rx * (rx - tx);
+ break;
+ case F54_ADC_RANGE:
+ if (m_f54Query.has_signal_clarity) {
+
+ retval = m_device.Read(m_f54Control.reg_41.address,
+ m_f54Control.reg_41.data,
+ sizeof(m_f54Control.reg_41.data));
+ if (retval < 0) {
+ m_reportSize = 0;
+ break;
+ }
+ if (m_f54Control.reg_41.no_signal_clarity) {
+ if (tx % 4)
+ tx += 4 - (tx % 4);
+ }
+ }
+ m_reportSize = 2 * tx * rx;
+ break;
+ case F54_TRX_OPENS:
+ case F54_TRX_TO_GND_SHORTS:
+ case F54_TRX_SHORTS:
+ m_reportSize = TRX_OPEN_SHORT_DATA_SIZE;
+ break;
+ case F54_ABS_RAW_CAP:
+ case F54_ABS_DELTA_CAP:
+ m_reportSize = 4 * (tx + rx);
+ break;
+ default:
+ m_reportSize = 0;
+ return TEST_FAIL_INVALID_PARAMETER;
+ }
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::FindTestFunctions()
+{
+ if (0 > m_device.ScanPDT(0x00, 10))
+ return TEST_FAIL_SCAN_PDT;
+
+ if (!m_device.GetFunction(m_f01, 0x01))
+ return TEST_FAIL_NO_FUNCTION_01;
+
+ if (!m_device.GetFunction(m_f54, 0x54))
+ return TEST_FAIL_NO_FUNCTION_54;
+
+ if (!m_device.GetFunction(m_f55, 0x55))
+ return TEST_FAIL_NO_FUNCTION_55;
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::ReadF54Queries()
+{
+ int retval;
+ unsigned short query_addr = m_f54.GetQueryBase();
+ unsigned char offset;
+
+ retval = m_device.Read(query_addr,
+ m_f54Query.data,
+ sizeof(m_f54Query.data));
+ if (retval < 0)
+ return retval;
+
+ offset = sizeof(m_f54Query.data);
+
+ /* query 12 */
+ if (m_f54Query.has_sense_frequency_control == 0)
+ offset -= 1;
+
+ /* query 13 */
+ if (m_f54Query.has_query13) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_13.data,
+ sizeof(m_f54Query_13.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 14 */
+ if ((m_f54Query.has_query13) && (m_f54Query_13.has_ctrl87))
+ offset += 1;
+
+ /* query 15 */
+ if (m_f54Query.has_query15) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_15.data,
+ sizeof(m_f54Query_15.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 16 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_query16)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_16.data,
+ sizeof(m_f54Query_16.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 17 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_query17))
+ offset += 1;
+
+ /* query 18 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl94_query18))
+ offset += 1;
+
+ /* query 19 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl95_query19))
+ offset += 1;
+
+ /* query 20 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_query20))
+ offset += 1;
+
+ /* query 21 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_query21)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_21.data,
+ sizeof(m_f54Query_21.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 22 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_query22)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_22.data,
+ sizeof(m_f54Query_22.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 23 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_query23)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_23.data,
+ sizeof(m_f54Query_23.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 24 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query21) &&
+ (m_f54Query_21.has_query24_data18))
+ offset += 1;
+
+ /* query 25 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_query25)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_25.data,
+ sizeof(m_f54Query_25.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 26 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_ctrl103_query26))
+ offset += 1;
+
+ /* query 27 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_27.data,
+ sizeof(m_f54Query_27.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 28 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_query28))
+ offset += 1;
+
+ /* query 29 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_29.data,
+ sizeof(m_f54Query_29.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 30 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_30.data,
+ sizeof(m_f54Query_30.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 31 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl122_query31))
+ offset += 1;
+
+ /* query 32 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_32.data,
+ sizeof(m_f54Query_32.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 33 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_33.data,
+ sizeof(m_f54Query_33.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 34 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query34))
+ offset += 1;
+
+ /* query 35 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query35)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_35.data,
+ sizeof(m_f54Query_35.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 36 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_36.data,
+ sizeof(m_f54Query_36.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ /* query 37 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_query37))
+ offset += 1;
+
+ /* query 38 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_query38)) {
+ retval = m_device.Read(query_addr + offset,
+ m_f54Query_38.data,
+ sizeof(m_f54Query_38.data));
+ if (retval < 0)
+ return retval;
+ offset += 1;
+ }
+
+ return TEST_SUCCESS;;
+}
+
+int F54Test::SetupF54Controls()
+{
+ unsigned char length;
+ unsigned char num_of_sensing_freqs;
+ unsigned short reg_addr = m_f54.GetControlBase();
+
+ num_of_sensing_freqs = m_f54Query.number_of_sensing_frequencies;
+
+ /* control 0 */
+ reg_addr += CONTROL_0_SIZE;
+
+ /* control 1 */
+ if ((m_f54Query.touch_controller_family == 0) ||
+ (m_f54Query.touch_controller_family == 1))
+ reg_addr += CONTROL_1_SIZE;
+
+ /* control 2 */
+ reg_addr += CONTROL_2_SIZE;
+
+ /* control 3 */
+ if (m_f54Query.has_pixel_touch_threshold_adjustment == 1)
+ reg_addr += CONTROL_3_SIZE;
+
+ /* controls 4 5 6 */
+ if ((m_f54Query.touch_controller_family == 0) ||
+ (m_f54Query.touch_controller_family == 1))
+ reg_addr += CONTROL_4_6_SIZE;
+
+ /* control 7 */
+ if (m_f54Query.touch_controller_family == 1) {
+ m_f54Control.reg_7.address = reg_addr;
+ reg_addr += CONTROL_7_SIZE;
+ }
+
+ /* controls 8 9 */
+ if ((m_f54Query.touch_controller_family == 0) ||
+ (m_f54Query.touch_controller_family == 1))
+ reg_addr += CONTROL_8_9_SIZE;
+
+ /* control 10 */
+ if (m_f54Query.has_interference_metric == 1)
+ reg_addr += CONTROL_10_SIZE;
+
+ /* control 11 */
+ if (m_f54Query.has_ctrl11 == 1)
+ reg_addr += CONTROL_11_SIZE;
+
+ /* controls 12 13 */
+ if (m_f54Query.has_relaxation_control == 1)
+ reg_addr += CONTROL_12_13_SIZE;
+
+ /* controls 14 15 16 */
+ if (m_f54Query.has_sensor_assignment == 1) {
+ reg_addr += CONTROL_14_SIZE;
+ reg_addr += CONTROL_15_SIZE * m_f54Query.num_of_rx_electrodes;
+ reg_addr += CONTROL_16_SIZE * m_f54Query.num_of_tx_electrodes;
+ }
+
+ /* controls 17 18 19 */
+ if (m_f54Query.has_sense_frequency_control == 1) {
+ reg_addr += CONTROL_17_SIZE * num_of_sensing_freqs;
+ reg_addr += CONTROL_18_SIZE * num_of_sensing_freqs;
+ reg_addr += CONTROL_19_SIZE * num_of_sensing_freqs;
+ }
+
+ /* control 20 */
+ reg_addr += CONTROL_20_SIZE;
+
+ /* control 21 */
+ if (m_f54Query.has_sense_frequency_control == 1)
+ reg_addr += CONTROL_21_SIZE;
+
+ /* controls 22 23 24 25 26 */
+ if (m_f54Query.has_firmware_noise_mitigation == 1)
+ reg_addr += CONTROL_22_26_SIZE;
+
+ /* control 27 */
+ if (m_f54Query.has_iir_filter == 1)
+ reg_addr += CONTROL_27_SIZE;
+
+ /* control 28 */
+ if (m_f54Query.has_firmware_noise_mitigation == 1)
+ reg_addr += CONTROL_28_SIZE;
+
+ /* control 29 */
+ if (m_f54Query.has_cmn_removal == 1)
+ reg_addr += CONTROL_29_SIZE;
+
+ /* control 30 */
+ if (m_f54Query.has_cmn_maximum == 1)
+ reg_addr += CONTROL_30_SIZE;
+
+ /* control 31 */
+ if (m_f54Query.has_touch_hysteresis == 1)
+ reg_addr += CONTROL_31_SIZE;
+
+ /* controls 32 33 34 35 */
+ if (m_f54Query.has_edge_compensation == 1)
+ reg_addr += CONTROL_32_35_SIZE;
+
+ /* control 36 */
+ if ((m_f54Query.curve_compensation_mode == 1) ||
+ (m_f54Query.curve_compensation_mode == 2)) {
+ if (m_f54Query.curve_compensation_mode == 1) {
+ length = std::max(m_f54Query.num_of_rx_electrodes,
+ m_f54Query.num_of_tx_electrodes);
+ } else if (m_f54Query.curve_compensation_mode == 2) {
+ length = m_f54Query.num_of_rx_electrodes;
+ }
+ reg_addr += CONTROL_36_SIZE * length;
+ }
+
+ /* control 37 */
+ if (m_f54Query.curve_compensation_mode == 2)
+ reg_addr += CONTROL_37_SIZE * m_f54Query.num_of_tx_electrodes;
+
+ /* controls 38 39 40 */
+ if (m_f54Query.has_per_frequency_noise_control == 1) {
+ reg_addr += CONTROL_38_SIZE * num_of_sensing_freqs;
+ reg_addr += CONTROL_39_SIZE * num_of_sensing_freqs;
+ reg_addr += CONTROL_40_SIZE * num_of_sensing_freqs;
+ }
+
+ /* control 41 */
+ if (m_f54Query.has_signal_clarity == 1) {
+ m_f54Control.reg_41.address = reg_addr;
+ reg_addr += CONTROL_41_SIZE;
+ }
+
+ /* control 42 */
+ if (m_f54Query.has_variance_metric == 1)
+ reg_addr += CONTROL_42_SIZE;
+
+ /* controls 43 44 45 46 47 48 49 50 51 52 53 54 */
+ if (m_f54Query.has_multi_metric_state_machine == 1)
+ reg_addr += CONTROL_43_54_SIZE;
+
+ /* controls 55 56 */
+ if (m_f54Query.has_0d_relaxation_control == 1)
+ reg_addr += CONTROL_55_56_SIZE;
+
+ /* control 57 */
+ if (m_f54Query.has_0d_acquisition_control == 1) {
+ m_f54Control.reg_57.address = reg_addr;
+ reg_addr += CONTROL_57_SIZE;
+ }
+
+ /* control 58 */
+ if (m_f54Query.has_0d_acquisition_control == 1)
+ reg_addr += CONTROL_58_SIZE;
+
+ /* control 59 */
+ if (m_f54Query.has_h_blank == 1)
+ reg_addr += CONTROL_59_SIZE;
+
+ /* controls 60 61 62 */
+ if ((m_f54Query.has_h_blank == 1) ||
+ (m_f54Query.has_v_blank == 1) ||
+ (m_f54Query.has_long_h_blank == 1))
+ reg_addr += CONTROL_60_62_SIZE;
+
+ /* control 63 */
+ if ((m_f54Query.has_h_blank == 1) ||
+ (m_f54Query.has_v_blank == 1) ||
+ (m_f54Query.has_long_h_blank == 1) ||
+ (m_f54Query.has_slew_metric == 1) ||
+ (m_f54Query.has_slew_option == 1) ||
+ (m_f54Query.has_noise_mitigation2 == 1))
+ reg_addr += CONTROL_63_SIZE;
+
+ /* controls 64 65 66 67 */
+ if (m_f54Query.has_h_blank == 1)
+ reg_addr += CONTROL_64_67_SIZE * 7;
+ else if ((m_f54Query.has_v_blank == 1) ||
+ (m_f54Query.has_long_h_blank == 1))
+ reg_addr += CONTROL_64_67_SIZE;
+
+ /* controls 68 69 70 71 72 73 */
+ if ((m_f54Query.has_h_blank == 1) ||
+ (m_f54Query.has_v_blank == 1) ||
+ (m_f54Query.has_long_h_blank == 1))
+ reg_addr += CONTROL_68_73_SIZE;
+
+ /* control 74 */
+ if (m_f54Query.has_slew_metric == 1)
+ reg_addr += CONTROL_74_SIZE;
+
+ /* control 75 */
+ if (m_f54Query.has_enhanced_stretch == 1)
+ reg_addr += CONTROL_75_SIZE * num_of_sensing_freqs;
+
+ /* control 76 */
+ if (m_f54Query.has_startup_fast_relaxation == 1)
+ reg_addr += CONTROL_76_SIZE;
+
+ /* controls 77 78 */
+ if (m_f54Query.has_esd_control == 1)
+ reg_addr += CONTROL_77_78_SIZE;
+
+ /* controls 79 80 81 82 83 */
+ if (m_f54Query.has_noise_mitigation2 == 1)
+ reg_addr += CONTROL_79_83_SIZE;
+
+ /* controls 84 85 */
+ if (m_f54Query.has_energy_ratio_relaxation == 1)
+ reg_addr += CONTROL_84_85_SIZE;
+
+ /* control 86 */
+ if ((m_f54Query.has_query13 == 1) && (m_f54Query_13.has_ctrl86 == 1))
+ reg_addr += CONTROL_86_SIZE;
+
+ /* control 87 */
+ if ((m_f54Query.has_query13 == 1) && (m_f54Query_13.has_ctrl87 == 1))
+ reg_addr += CONTROL_87_SIZE;
+
+ /* control 88 */
+ if (m_f54Query.has_ctrl88 == 1) {
+ m_f54Control.reg_88.address = reg_addr;
+ reg_addr += CONTROL_88_SIZE;
+ }
+
+ /* control 89 */
+ if ((m_f54Query.has_query13 == 1) &&
+ (m_f54Query_13.has_cidim == 1 ||
+ m_f54Query_13.has_noise_mitigation_enhancement ||
+ m_f54Query_13.has_rail_im))
+ reg_addr += CONTROL_89_SIZE;
+
+ /* control 90 */
+ if ((m_f54Query.has_query15) && (m_f54Query_15.has_ctrl90))
+ reg_addr += CONTROL_90_SIZE;
+
+ /* control 91 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query21) &&
+ (m_f54Query_21.has_ctrl91))
+ reg_addr += CONTROL_91_SIZE;
+
+ /* control 92 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl92))
+ reg_addr += CONTROL_92_SIZE;
+
+ /* control 93 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl93))
+ reg_addr += CONTROL_93_SIZE;
+
+ /* control 94 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl94_query18))
+ reg_addr += CONTROL_94_SIZE;
+
+ /* control 95 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl95_query19))
+ reg_addr += CONTROL_95_SIZE;
+
+ /* control 96 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query21) &&
+ (m_f54Query_21.has_ctrl96))
+ reg_addr += CONTROL_96_SIZE;
+
+ /* control 97 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query21) &&
+ (m_f54Query_21.has_ctrl97))
+ reg_addr += CONTROL_97_SIZE;
+
+ /* control 98 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query21) &&
+ (m_f54Query_21.has_ctrl98))
+ reg_addr += CONTROL_98_SIZE;
+
+ /* control 99 */
+ if (m_f54Query.touch_controller_family == 2)
+ reg_addr += CONTROL_99_SIZE;
+
+ /* control 100 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query16) &&
+ (m_f54Query_16.has_ctrl100))
+ reg_addr += CONTROL_100_SIZE;
+
+ /* control 101 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_ctrl101))
+ reg_addr += CONTROL_101_SIZE;
+
+
+ /* control 102 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_query23) &&
+ (m_f54Query_23.has_ctrl102))
+ reg_addr += CONTROL_102_SIZE;
+
+ /* control 103 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_ctrl103_query26))
+ reg_addr += CONTROL_103_SIZE;
+
+ /* control 104 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_ctrl104))
+ reg_addr += CONTROL_104_SIZE;
+
+ /* control 105 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query22) &&
+ (m_f54Query_22.has_ctrl105))
+ reg_addr += CONTROL_105_SIZE;
+
+ /* control 106 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_ctrl106))
+ reg_addr += CONTROL_106_SIZE;
+
+ /* control 107 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_ctrl107))
+ reg_addr += CONTROL_107_SIZE;
+
+ /* control 108 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_ctrl108))
+ reg_addr += CONTROL_108_SIZE;
+
+ /* control 109 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_ctrl109))
+ reg_addr += CONTROL_109_SIZE;
+
+ /* control 110 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_ctrl110)) {
+ m_f54Control.reg_110.address = reg_addr;
+ reg_addr += CONTROL_110_SIZE;
+ }
+
+ /* control 111 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_ctrl111))
+ reg_addr += CONTROL_111_SIZE;
+
+ /* control 112 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_ctrl112))
+ reg_addr += CONTROL_112_SIZE;
+
+ /* control 113 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_ctrl113))
+ reg_addr += CONTROL_113_SIZE;
+
+ /* control 114 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_ctrl114))
+ reg_addr += CONTROL_114_SIZE;
+
+ /* control 115 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_ctrl115))
+ reg_addr += CONTROL_115_SIZE;
+
+ /* control 116 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_ctrl116))
+ reg_addr += CONTROL_116_SIZE;
+
+ /* control 117 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_ctrl117))
+ reg_addr += CONTROL_117_SIZE;
+
+ /* control 118 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl118))
+ reg_addr += CONTROL_118_SIZE;
+
+ /* control 119 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl119))
+ reg_addr += CONTROL_119_SIZE;
+
+ /* control 120 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl120))
+ reg_addr += CONTROL_120_SIZE;
+
+ /* control 121 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl121))
+ reg_addr += CONTROL_121_SIZE;
+
+ /* control 122 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl122_query31))
+ reg_addr += CONTROL_122_SIZE;
+
+ /* control 123 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_ctrl123))
+ reg_addr += CONTROL_123_SIZE;
+
+ /* control 124 reserved */
+
+ /* control 125 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_ctrl125))
+ reg_addr += CONTROL_125_SIZE;
+
+ /* control 126 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_ctrl126))
+ reg_addr += CONTROL_126_SIZE;
+
+ /* control 127 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_ctrl127))
+ reg_addr += CONTROL_127_SIZE;
+
+ /* controls 128 129 130 131 reserved */
+
+ /* control 132 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_ctrl132))
+ reg_addr += CONTROL_132_SIZE;
+
+ /* control 133 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_ctrl133))
+ reg_addr += CONTROL_133_SIZE;
+
+ /* control 134 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_ctrl134))
+ reg_addr += CONTROL_134_SIZE;
+
+ /* controls 135 136 reserved */
+
+ /* control 137 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query35) &&
+ (m_f54Query_35.has_ctrl137))
+ reg_addr += CONTROL_137_SIZE;
+
+ /* control 138 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query35) &&
+ (m_f54Query_35.has_ctrl138))
+ reg_addr += CONTROL_138_SIZE;
+
+ /* control 139 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query35) &&
+ (m_f54Query_35.has_ctrl139))
+ reg_addr += CONTROL_139_SIZE;
+
+ /* control 140 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query35) &&
+ (m_f54Query_35.has_ctrl140))
+ reg_addr += CONTROL_140_SIZE;
+
+ /* control 141 reserved */
+
+ /* control 142 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_ctrl142))
+ reg_addr += CONTROL_142_SIZE;
+
+ /* control 143 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_ctrl143))
+ reg_addr += CONTROL_143_SIZE;
+
+ /* control 144 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_ctrl144))
+ reg_addr += CONTROL_144_SIZE;
+
+ /* control 145 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_ctrl145))
+ reg_addr += CONTROL_145_SIZE;
+
+ /* control 146 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_ctrl146))
+ reg_addr += CONTROL_146_SIZE;
+
+ /* control 147 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_query38) &&
+ (m_f54Query_38.has_ctrl147))
+ reg_addr += CONTROL_147_SIZE;
+
+ /* control 148 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_query38) &&
+ (m_f54Query_38.has_ctrl148))
+ reg_addr += CONTROL_148_SIZE;
+
+ /* control 149 */
+ if ((m_f54Query.has_query15) &&
+ (m_f54Query_15.has_query25) &&
+ (m_f54Query_25.has_query27) &&
+ (m_f54Query_27.has_query29) &&
+ (m_f54Query_29.has_query30) &&
+ (m_f54Query_30.has_query32) &&
+ (m_f54Query_32.has_query33) &&
+ (m_f54Query_33.has_query36) &&
+ (m_f54Query_36.has_query38) &&
+ (m_f54Query_38.has_ctrl149)) {
+ m_f54Control.reg_149.address = reg_addr;
+ reg_addr += CONTROL_149_SIZE;
+ }
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::ReadF55Queries()
+{
+ int retval;
+ unsigned char ii;
+ unsigned char rx_electrodes = m_f54Query.num_of_rx_electrodes;
+ unsigned char tx_electrodes = m_f54Query.num_of_tx_electrodes;
+
+ retval = m_device.Read(m_f55.GetQueryBase(),
+ m_f55Query.data,
+ sizeof(m_f55Query.data));
+ if (retval < 0) {
+ return retval;
+ }
+
+ if (!m_f55Query.has_sensor_assignment)
+ {
+ m_txAssigned = tx_electrodes;
+ m_rxAssigned = rx_electrodes;
+ m_txAssignment = NULL;
+ m_rxAssignment = NULL;
+ return TEST_SUCCESS;
+ }
+
+ if (m_txAssignment != NULL) delete [] m_txAssignment;
+ if (m_rxAssignment != NULL) delete [] m_rxAssignment;
+ m_txAssignment = new unsigned char[tx_electrodes];
+ m_rxAssignment = new unsigned char[rx_electrodes];
+
+ retval = m_device.Read(m_f55.GetControlBase() + SENSOR_TX_MAPPING_OFFSET,
+ m_txAssignment,
+ tx_electrodes);
+ if (retval < 0) {
+ goto exit;
+ }
+
+ retval = m_device.Read(m_f55.GetControlBase() + SENSOR_RX_MAPPING_OFFSET,
+ m_rxAssignment,
+ rx_electrodes);
+ if (retval < 0) {
+ goto exit;
+ }
+
+ m_txAssigned = 0;
+ for (ii = 0; ii < tx_electrodes; ii++) {
+ if (m_txAssignment[ii] != 0xff)
+ m_txAssigned++;
+ }
+
+ m_rxAssigned = 0;
+ for (ii = 0; ii < rx_electrodes; ii++) {
+ if (m_rxAssignment[ii] != 0xff)
+ m_rxAssigned++;
+ }
+
+ return TEST_SUCCESS;
+
+exit:
+ if (m_txAssignment != NULL)
+ {
+ delete [] m_txAssignment;
+ m_txAssignment = NULL;
+ }
+ if (m_rxAssignment != NULL)
+ {
+ delete [] m_rxAssignment;
+ m_rxAssignment = NULL;
+ }
+
+ return retval;
+}
+
+int F54Test::SetF54Interrupt()
+{
+ int retval;
+ unsigned char mask = m_f54.GetInterruptMask();
+ unsigned char zero = 0;
+ unsigned int i;
+
+ for (i = 0; i < m_device.GetNumInterruptRegs(); i++)
+ {
+ if (i == m_f54.GetInterruptRegNum())
+ {
+ retval = m_device.Write(m_f54.GetControlBase() + 1 + i, &mask, 1);
+ }
+ else
+ {
+ retval = m_device.Write(m_f54.GetControlBase() + 1 + i, &zero, 1);
+ }
+
+ if (retval < 0)
+ return retval;
+ }
+ return TEST_SUCCESS;
+}
+
+int F54Test::DoF54Command(unsigned char command)
+{
+ int retval;
+
+ retval = m_device.Write(m_f54.GetCommandBase(), &command, 1);
+ if (retval < 0)
+ return retval;
+
+ retval = WaitForF54CommandCompletion();
+ if (retval != TEST_SUCCESS)
+ return retval;
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::WaitForF54CommandCompletion()
+{
+ int retval;
+ unsigned char value;
+ unsigned char timeout_count;
+
+ timeout_count = 0;
+ do {
+ retval = m_device.Read(m_f54.GetCommandBase(),
+ &value,
+ sizeof(value));
+ if (retval < 0)
+ return retval;
+
+ if (value == 0x00)
+ break;
+
+ Sleep(100);
+ timeout_count++;
+ } while (timeout_count < COMMAND_TIMEOUT_100MS);
+
+ if (timeout_count == COMMAND_TIMEOUT_100MS) {
+ return -ETIMEDOUT;
+ }
+
+ return TEST_SUCCESS;
+}
+
+int F54Test::ReadF54Report()
+{
+ int retval;
+ unsigned char report_index[2];
+
+ if (m_reportBufferSize < m_reportSize) {
+ if (m_reportData != NULL)
+ delete [] m_reportData;
+ m_reportData = new unsigned char[m_reportSize];
+ if (!m_reportData) {
+ m_reportBufferSize = 0;
+ retval = TEST_FAIL_MEMORY_ALLOCATION;
+ goto exit;
+ }
+ m_reportBufferSize = m_reportSize;
+ }
+
+ report_index[0] = 0;
+ report_index[1] = 0;
+
+ retval = m_device.Write(m_f54.GetDataBase() + REPORT_INDEX_OFFSET,
+ report_index,
+ sizeof(report_index));
+
+ if (retval < 0)
+ goto exit;
+
+ retval = m_device.Read(m_f54.GetDataBase() + REPORT_DATA_OFFSET,
+ m_reportData,
+ m_reportSize);
+ if (retval < 0)
+ goto exit;
+
+ return TEST_SUCCESS;
+
+exit:
+ if (m_reportData != NULL)
+ {
+ delete [] m_reportData;
+ m_reportData = NULL;
+ }
+
+ return retval;
+}
+
+int F54Test::ShowF54Report()
+{
+ unsigned int ii;
+ unsigned int jj;
+ unsigned int tx_num = m_txAssigned;
+ unsigned int rx_num = m_rxAssigned;
+ char *report_data_8;
+ short *report_data_16;
+ int *report_data_32;
+ unsigned int *report_data_u32;
+ char buf[256];
+
+ switch (m_reportType) {
+ case F54_8BIT_IMAGE:
+ report_data_8 = (char *)m_reportData;
+ for (ii = 0; ii < m_reportSize; ii++) {
+ sprintf(buf, "%03d: %d\n",
+ ii, *report_data_8);
+ m_display.Output(buf);
+ report_data_8++;
+ }
+ break;
+ case F54_16BIT_IMAGE:
+ case F54_RAW_16BIT_IMAGE:
+ case F54_TRUE_BASELINE:
+ case F54_FULL_RAW_CAP:
+ case F54_FULL_RAW_CAP_NO_RX_COUPLING:
+ case F54_SENSOR_SPEED:
+ report_data_16 = (short *)m_reportData;
+ sprintf(buf, "tx = %d\nrx = %d\n",
+ tx_num, rx_num);
+ m_display.Output(buf);
+
+ for (ii = 0; ii < tx_num; ii++) {
+ for (jj = 0; jj < (rx_num - 1); jj++) {
+ sprintf(buf, "%-4d ",
+ *report_data_16);
+ report_data_16++;
+ m_display.Output(buf);
+ }
+ sprintf(buf, "%-4d\n",
+ *report_data_16);
+ m_display.Output(buf);
+ report_data_16++;
+ }
+ break;
+ case F54_HIGH_RESISTANCE:
+ case F54_FULL_RAW_CAP_MIN_MAX:
+ report_data_16 = (short *)m_reportData;
+ for (ii = 0; ii < m_reportSize; ii += 2) {
+ sprintf(buf, "%03d: %d\n",
+ ii / 2, *report_data_16);
+ m_display.Output(buf);
+ report_data_16++;
+ }
+ break;
+ case F54_ABS_RAW_CAP:
+ report_data_u32 = (unsigned int *)m_reportData;
+ sprintf(buf, "rx ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < rx_num; ii++) {
+ sprintf(buf, " %2d", ii);
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, " ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < rx_num; ii++) {
+ sprintf(buf, " %5u",
+ *report_data_u32);
+ report_data_u32++;
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, "tx ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < tx_num; ii++) {
+ sprintf(buf, " %2d", ii);
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, " ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < tx_num; ii++) {
+ sprintf(buf, " %5u",
+ *report_data_u32);
+ report_data_u32++;
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ break;
+ case F54_ABS_DELTA_CAP:
+ report_data_32 = (int *)m_reportData;
+ sprintf(buf, "rx ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < rx_num; ii++) {
+ sprintf(buf, " %2d", ii);
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, " ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < rx_num; ii++) {
+ sprintf(buf, " %5d",
+ *report_data_32);
+ report_data_32++;
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, "tx ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < tx_num; ii++) {
+ sprintf(buf, " %2d", ii);
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ sprintf(buf, " ");
+ m_display.Output(buf);
+
+ for (ii = 0; ii < tx_num; ii++) {
+ sprintf(buf, " %5d",
+ *report_data_32);
+ report_data_32++;
+ m_display.Output(buf);
+ }
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ break;
+ default:
+ for (ii = 0; ii < m_reportSize; ii++) {
+ sprintf(buf, "%03d: 0x%02x\n",
+ ii, m_reportData[ii]);
+ m_display.Output(buf);
+ }
+ break;
+ }
+
+ sprintf(buf, "\n");
+ m_display.Output(buf);
+
+ m_display.Reflesh();
+
+ return TEST_SUCCESS;
+}
diff --git a/f54test/f54test.h b/f54test/f54test.h
new file mode 100644
index 0000000..6842cba
--- /dev/null
+++ b/f54test/f54test.h
@@ -0,0 +1,709 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _F54TEST_H_
+#define _F54TEST_H_
+
+#include "rmidevice.h"
+
+#define COMMAND_TIMEOUT_100MS 20
+
+#define COMMAND_GET_REPORT 1
+#define COMMAND_FORCE_CAL 2
+#define COMMAND_FORCE_UPDATE 4
+
+#define REPORT_INDEX_OFFSET 1
+#define REPORT_DATA_OFFSET 3
+
+#define SENSOR_RX_MAPPING_OFFSET 1
+#define SENSOR_TX_MAPPING_OFFSET 2
+
+#define CONTROL_0_SIZE 1
+#define CONTROL_1_SIZE 1
+#define CONTROL_2_SIZE 2
+#define CONTROL_3_SIZE 1
+#define CONTROL_4_6_SIZE 3
+#define CONTROL_7_SIZE 1
+#define CONTROL_8_9_SIZE 3
+#define CONTROL_10_SIZE 1
+#define CONTROL_11_SIZE 2
+#define CONTROL_12_13_SIZE 2
+#define CONTROL_14_SIZE 1
+#define CONTROL_15_SIZE 1
+#define CONTROL_16_SIZE 1
+#define CONTROL_17_SIZE 1
+#define CONTROL_18_SIZE 1
+#define CONTROL_19_SIZE 1
+#define CONTROL_20_SIZE 1
+#define CONTROL_21_SIZE 2
+#define CONTROL_22_26_SIZE 7
+#define CONTROL_27_SIZE 1
+#define CONTROL_28_SIZE 2
+#define CONTROL_29_SIZE 1
+#define CONTROL_30_SIZE 1
+#define CONTROL_31_SIZE 1
+#define CONTROL_32_35_SIZE 8
+#define CONTROL_36_SIZE 1
+#define CONTROL_37_SIZE 1
+#define CONTROL_38_SIZE 1
+#define CONTROL_39_SIZE 1
+#define CONTROL_40_SIZE 1
+#define CONTROL_41_SIZE 1
+#define CONTROL_42_SIZE 2
+#define CONTROL_43_54_SIZE 13
+#define CONTROL_55_56_SIZE 2
+#define CONTROL_57_SIZE 1
+#define CONTROL_58_SIZE 1
+#define CONTROL_59_SIZE 2
+#define CONTROL_60_62_SIZE 3
+#define CONTROL_63_SIZE 1
+#define CONTROL_64_67_SIZE 4
+#define CONTROL_68_73_SIZE 8
+#define CONTROL_74_SIZE 2
+#define CONTROL_75_SIZE 1
+#define CONTROL_76_SIZE 1
+#define CONTROL_77_78_SIZE 2
+#define CONTROL_79_83_SIZE 5
+#define CONTROL_84_85_SIZE 2
+#define CONTROL_86_SIZE 1
+#define CONTROL_87_SIZE 1
+#define CONTROL_88_SIZE 1
+#define CONTROL_89_SIZE 1
+#define CONTROL_90_SIZE 1
+#define CONTROL_91_SIZE 1
+#define CONTROL_92_SIZE 1
+#define CONTROL_93_SIZE 1
+#define CONTROL_94_SIZE 1
+#define CONTROL_95_SIZE 1
+#define CONTROL_96_SIZE 1
+#define CONTROL_97_SIZE 1
+#define CONTROL_98_SIZE 1
+#define CONTROL_99_SIZE 1
+#define CONTROL_100_SIZE 1
+#define CONTROL_101_SIZE 1
+#define CONTROL_102_SIZE 1
+#define CONTROL_103_SIZE 1
+#define CONTROL_104_SIZE 1
+#define CONTROL_105_SIZE 1
+#define CONTROL_106_SIZE 1
+#define CONTROL_107_SIZE 1
+#define CONTROL_108_SIZE 1
+#define CONTROL_109_SIZE 1
+#define CONTROL_110_SIZE 1
+#define CONTROL_111_SIZE 1
+#define CONTROL_112_SIZE 1
+#define CONTROL_113_SIZE 1
+#define CONTROL_114_SIZE 1
+#define CONTROL_115_SIZE 1
+#define CONTROL_116_SIZE 1
+#define CONTROL_117_SIZE 1
+#define CONTROL_118_SIZE 1
+#define CONTROL_119_SIZE 1
+#define CONTROL_120_SIZE 1
+#define CONTROL_121_SIZE 1
+#define CONTROL_122_SIZE 1
+#define CONTROL_123_SIZE 1
+#define CONTROL_124_SIZE 1
+#define CONTROL_125_SIZE 1
+#define CONTROL_126_SIZE 1
+#define CONTROL_127_SIZE 1
+#define CONTROL_128_SIZE 1
+#define CONTROL_129_SIZE 1
+#define CONTROL_130_SIZE 1
+#define CONTROL_131_SIZE 1
+#define CONTROL_132_SIZE 1
+#define CONTROL_133_SIZE 1
+#define CONTROL_134_SIZE 1
+#define CONTROL_135_SIZE 1
+#define CONTROL_136_SIZE 1
+#define CONTROL_137_SIZE 1
+#define CONTROL_138_SIZE 1
+#define CONTROL_139_SIZE 1
+#define CONTROL_140_SIZE 1
+#define CONTROL_141_SIZE 1
+#define CONTROL_142_SIZE 1
+#define CONTROL_143_SIZE 1
+#define CONTROL_144_SIZE 1
+#define CONTROL_145_SIZE 1
+#define CONTROL_146_SIZE 1
+#define CONTROL_147_SIZE 1
+#define CONTROL_148_SIZE 1
+#define CONTROL_149_SIZE 1
+
+#define HIGH_RESISTANCE_DATA_SIZE 6
+#define FULL_RAW_CAP_MIN_MAX_DATA_SIZE 4
+#define TRX_OPEN_SHORT_DATA_SIZE 7
+
+enum f54_report_types {
+ F54_8BIT_IMAGE = 1,
+ F54_16BIT_IMAGE = 2,
+ F54_RAW_16BIT_IMAGE = 3,
+ F54_HIGH_RESISTANCE = 4,
+ F54_TX_TO_TX_SHORTS = 5,
+ F54_RX_TO_RX_SHORTS_1 = 7,
+ F54_TRUE_BASELINE = 9,
+ F54_FULL_RAW_CAP_MIN_MAX = 13,
+ F54_RX_OPENS_1 = 14,
+ F54_TX_OPENS = 15,
+ F54_TX_TO_GND_SHORTS = 16,
+ F54_RX_TO_RX_SHORTS_2 = 17,
+ F54_RX_OPENS_2 = 18,
+ F54_FULL_RAW_CAP = 19,
+ F54_FULL_RAW_CAP_NO_RX_COUPLING = 20,
+ F54_SENSOR_SPEED = 22,
+ F54_ADC_RANGE = 23,
+ F54_TRX_OPENS = 24,
+ F54_TRX_TO_GND_SHORTS = 25,
+ F54_TRX_SHORTS = 26,
+ F54_ABS_RAW_CAP = 38,
+ F54_ABS_DELTA_CAP = 40,
+ INVALID_REPORT_TYPE = -1,
+};
+
+struct f54_query {
+ union {
+ struct {
+ /* query 0 */
+ unsigned char num_of_rx_electrodes;
+
+ /* query 1 */
+ unsigned char num_of_tx_electrodes;
+
+ /* query 2 */
+ unsigned char f54_query2_b0__1:2;
+ unsigned char has_baseline:1;
+ unsigned char has_image8:1;
+ unsigned char f54_query2_b4__5:2;
+ unsigned char has_image16:1;
+ unsigned char f54_query2_b7:1;
+
+ /* queries 3.0 and 3.1 */
+ unsigned short clock_rate;
+
+ /* query 4 */
+ unsigned char touch_controller_family;
+
+ /* query 5 */
+ unsigned char has_pixel_touch_threshold_adjustment:1;
+ unsigned char f54_query5_b1__7:7;
+
+ /* query 6 */
+ unsigned char has_sensor_assignment:1;
+ unsigned char has_interference_metric:1;
+ unsigned char has_sense_frequency_control:1;
+ unsigned char has_firmware_noise_mitigation:1;
+ unsigned char has_ctrl11:1;
+ unsigned char has_two_byte_report_rate:1;
+ unsigned char has_one_byte_report_rate:1;
+ unsigned char has_relaxation_control:1;
+
+ /* query 7 */
+ unsigned char curve_compensation_mode:2;
+ unsigned char f54_query7_b2__7:6;
+
+ /* query 8 */
+ unsigned char f54_query8_b0:1;
+ unsigned char has_iir_filter:1;
+ unsigned char has_cmn_removal:1;
+ unsigned char has_cmn_maximum:1;
+ unsigned char has_touch_hysteresis:1;
+ unsigned char has_edge_compensation:1;
+ unsigned char has_per_frequency_noise_control:1;
+ unsigned char has_enhanced_stretch:1;
+
+ /* query 9 */
+ unsigned char has_force_fast_relaxation:1;
+ unsigned char has_multi_metric_state_machine:1;
+ unsigned char has_signal_clarity:1;
+ unsigned char has_variance_metric:1;
+ unsigned char has_0d_relaxation_control:1;
+ unsigned char has_0d_acquisition_control:1;
+ unsigned char has_status:1;
+ unsigned char has_slew_metric:1;
+
+ /* query 10 */
+ unsigned char has_h_blank:1;
+ unsigned char has_v_blank:1;
+ unsigned char has_long_h_blank:1;
+ unsigned char has_startup_fast_relaxation:1;
+ unsigned char has_esd_control:1;
+ unsigned char has_noise_mitigation2:1;
+ unsigned char has_noise_state:1;
+ unsigned char has_energy_ratio_relaxation:1;
+
+ /* query 11 */
+ unsigned char has_excessive_noise_reporting:1;
+ unsigned char has_slew_option:1;
+ unsigned char has_two_overhead_bursts:1;
+ unsigned char has_query13:1;
+ unsigned char has_one_overhead_burst:1;
+ unsigned char f54_query11_b5:1;
+ unsigned char has_ctrl88:1;
+ unsigned char has_query15:1;
+
+ /* query 12 */
+ unsigned char number_of_sensing_frequencies:4;
+ unsigned char f54_query12_b4__7:4;
+ } __attribute__((packed));
+ unsigned char data[14];
+ };
+};
+
+struct f54_query_13 {
+ union {
+ struct {
+ unsigned char has_ctrl86:1;
+ unsigned char has_ctrl87:1;
+ unsigned char has_ctrl87_sub0:1;
+ unsigned char has_ctrl87_sub1:1;
+ unsigned char has_ctrl87_sub2:1;
+ unsigned char has_cidim:1;
+ unsigned char has_noise_mitigation_enhancement:1;
+ unsigned char has_rail_im:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_15 {
+ union {
+ struct {
+ unsigned char has_ctrl90:1;
+ unsigned char has_transmit_strength:1;
+ unsigned char has_ctrl87_sub3:1;
+ unsigned char has_query16:1;
+ unsigned char has_query20:1;
+ unsigned char has_query21:1;
+ unsigned char has_query22:1;
+ unsigned char has_query25:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_16 {
+ union {
+ struct {
+ unsigned char has_query17:1;
+ unsigned char has_data17:1;
+ unsigned char has_ctrl92:1;
+ unsigned char has_ctrl93:1;
+ unsigned char has_ctrl94_query18:1;
+ unsigned char has_ctrl95_query19:1;
+ unsigned char has_ctrl99:1;
+ unsigned char has_ctrl100:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_21 {
+ union {
+ struct {
+ unsigned char has_abs_rx:1;
+ unsigned char has_abs_tx:1;
+ unsigned char has_ctrl91:1;
+ unsigned char has_ctrl96:1;
+ unsigned char has_ctrl97:1;
+ unsigned char has_ctrl98:1;
+ unsigned char has_data19:1;
+ unsigned char has_query24_data18:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_22 {
+ union {
+ struct {
+ unsigned char has_packed_image:1;
+ unsigned char has_ctrl101:1;
+ unsigned char has_dynamic_sense_display_ratio:1;
+ unsigned char has_query23:1;
+ unsigned char has_ctrl103_query26:1;
+ unsigned char has_ctrl104:1;
+ unsigned char has_ctrl105:1;
+ unsigned char has_query28:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_23 {
+ union {
+ struct {
+ unsigned char has_ctrl102:1;
+ unsigned char has_ctrl102_sub1:1;
+ unsigned char has_ctrl102_sub2:1;
+ unsigned char has_ctrl102_sub4:1;
+ unsigned char has_ctrl102_sub5:1;
+ unsigned char has_ctrl102_sub9:1;
+ unsigned char has_ctrl102_sub10:1;
+ unsigned char has_ctrl102_sub11:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_25 {
+ union {
+ struct {
+ unsigned char has_ctrl106:1;
+ unsigned char has_ctrl102_sub12:1;
+ unsigned char has_ctrl107:1;
+ unsigned char has_ctrl108:1;
+ unsigned char has_ctrl109:1;
+ unsigned char has_data20:1;
+ unsigned char f54_query25_b6:1;
+ unsigned char has_query27:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_27 {
+ union {
+ struct {
+ unsigned char has_ctrl110:1;
+ unsigned char has_data21:1;
+ unsigned char has_ctrl111:1;
+ unsigned char has_ctrl112:1;
+ unsigned char has_ctrl113:1;
+ unsigned char has_data22:1;
+ unsigned char has_ctrl114:1;
+ unsigned char has_query29:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_29 {
+ union {
+ struct {
+ unsigned char has_ctrl115:1;
+ unsigned char has_ground_ring_options:1;
+ unsigned char has_lost_bursts_tuning:1;
+ unsigned char has_aux_exvcom2_select:1;
+ unsigned char has_ctrl116:1;
+ unsigned char has_data23:1;
+ unsigned char has_ctrl117:1;
+ unsigned char has_query30:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_30 {
+ union {
+ struct {
+ unsigned char has_ctrl118:1;
+ unsigned char has_ctrl119:1;
+ unsigned char has_ctrl120:1;
+ unsigned char has_ctrl121:1;
+ unsigned char has_ctrl122_query31:1;
+ unsigned char has_ctrl123:1;
+ unsigned char f54_query30_b6:1;
+ unsigned char has_query32:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_32 {
+ union {
+ struct {
+ unsigned char has_ctrl125:1;
+ unsigned char has_ctrl126:1;
+ unsigned char has_ctrl127:1;
+ unsigned char has_abs_charge_pump_disable:1;
+ unsigned char has_query33:1;
+ unsigned char has_data24:1;
+ unsigned char has_query34:1;
+ unsigned char has_query35:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_33 {
+ union {
+ struct {
+ unsigned char f54_query33_b0:1;
+ unsigned char f54_query33_b1:1;
+ unsigned char f54_query33_b2:1;
+ unsigned char f54_query33_b3:1;
+ unsigned char has_ctrl132:1;
+ unsigned char has_ctrl133:1;
+ unsigned char has_ctrl134:1;
+ unsigned char has_query36:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_35 {
+ union {
+ struct {
+ unsigned char has_data25:1;
+ unsigned char f54_query35_b1:1;
+ unsigned char f54_query35_b2:1;
+ unsigned char has_ctrl137:1;
+ unsigned char has_ctrl138:1;
+ unsigned char has_ctrl139:1;
+ unsigned char has_data26:1;
+ unsigned char has_ctrl140:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_36 {
+ union {
+ struct {
+ unsigned char f54_query36_b0:1;
+ unsigned char has_ctrl142:1;
+ unsigned char has_query37:1;
+ unsigned char has_ctrl143:1;
+ unsigned char has_ctrl144:1;
+ unsigned char has_ctrl145:1;
+ unsigned char has_ctrl146:1;
+ unsigned char has_query38:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_query_38 {
+ union {
+ struct {
+ unsigned char has_ctrl147:1;
+ unsigned char has_ctrl148:1;
+ unsigned char has_ctrl149:1;
+ unsigned char f54_query38_b3:1;
+ unsigned char f54_query38_b4:1;
+ unsigned char f54_query38_b5:1;
+ unsigned char f54_query38_b6:1;
+ unsigned char f54_query38_b7:1;
+ } __attribute__((packed));
+ unsigned char data[1];
+ };
+};
+
+struct f54_control_7 {
+ union {
+ struct {
+ unsigned char cbc_cap:3;
+ unsigned char cbc_polarity:1;
+ unsigned char cbc_tx_carrier_selection:1;
+ unsigned char f54_ctrl7_b5__7:3;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[1];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control_41 {
+ union {
+ struct {
+ unsigned char no_signal_clarity:1;
+ unsigned char f54_ctrl41_b1__7:7;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[1];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control_57 {
+ union {
+ struct {
+ unsigned char cbc_cap:3;
+ unsigned char cbc_polarity:1;
+ unsigned char cbc_tx_carrier_selection:1;
+ unsigned char f54_ctrl57_b5__7:3;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[1];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control_88 {
+ union {
+ struct {
+ unsigned char tx_low_reference_polarity:1;
+ unsigned char tx_high_reference_polarity:1;
+ unsigned char abs_low_reference_polarity:1;
+ unsigned char abs_polarity:1;
+ unsigned char cbc_polarity:1;
+ unsigned char cbc_tx_carrier_selection:1;
+ unsigned char charge_pump_enable:1;
+ unsigned char cbc_abs_auto_servo:1;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[1];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control_110 {
+ union {
+ struct {
+ unsigned char active_stylus_rx_feedback_cap;
+ unsigned char active_stylus_rx_feedback_cap_reference;
+ unsigned char active_stylus_low_reference;
+ unsigned char active_stylus_high_reference;
+ unsigned char active_stylus_gain_control;
+ unsigned char active_stylus_gain_control_reference;
+ unsigned char active_stylus_timing_mode;
+ unsigned char active_stylus_discovery_bursts;
+ unsigned char active_stylus_detection_bursts;
+ unsigned char active_stylus_discovery_noise_multiplier;
+ unsigned char active_stylus_detection_envelope_min;
+ unsigned char active_stylus_detection_envelope_max;
+ unsigned char active_stylus_lose_count;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[13];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control_149 {
+ union {
+ struct {
+ unsigned char trans_cbc_global_cap_enable:1;
+ unsigned char f54_ctrl49_b1__7:7;
+ } __attribute__((packed));
+ struct {
+ unsigned char data[1];
+ unsigned short address;
+ } __attribute__((packed));
+ };
+};
+
+struct f54_control {
+ struct f54_control_7 reg_7;
+ struct f54_control_41 reg_41;
+ struct f54_control_57 reg_57;
+ struct f54_control_88 reg_88;
+ struct f54_control_110 reg_110;
+ struct f54_control_149 reg_149;
+};
+
+struct f55_query {
+ union {
+ struct {
+ /* query 0 */
+ unsigned char num_of_rx_electrodes;
+
+ /* query 1 */
+ unsigned char num_of_tx_electrodes;
+
+ /* query 2 */
+ unsigned char has_sensor_assignment:1;
+ unsigned char has_edge_compensation:1;
+ unsigned char curve_compensation_mode:2;
+ unsigned char has_ctrl6:1;
+ unsigned char has_alternate_transmitter_assignment:1;
+ unsigned char has_single_layer_multi_touch:1;
+ unsigned char has_query5:1;
+ } __attribute__((packed));
+ unsigned char data[3];
+ };
+};
+
+class Display;
+
+class F54Test
+{
+public:
+ F54Test(RMIDevice & device, Display & display)
+ : m_device(device),
+ m_reportType(INVALID_REPORT_TYPE),
+ m_txAssignment(NULL),
+ m_rxAssignment(NULL),
+ m_reportBufferSize(0),
+ m_reportData(NULL),
+ m_display(display)
+ {}
+ ~F54Test();
+ int Prepare(f54_report_types reportType);
+ int Run();
+
+private:
+ int FindTestFunctions();
+ int ReadF54Queries();
+ int ReadF55Queries();
+ int SetupF54Controls();
+ int SetF54ReportType(f54_report_types report_type);
+ int SetF54ReportSize(f54_report_types report_type);
+ int SetF54Interrupt();
+ int DoF54Command(unsigned char command);
+ int WaitForF54CommandCompletion();
+ int ReadF54Report();
+ int ShowF54Report();
+
+private:
+ RMIDevice & m_device;
+
+ RMIFunction m_f01;
+ RMIFunction m_f54;
+ RMIFunction m_f55;
+
+ f54_query m_f54Query;
+ f54_query_13 m_f54Query_13;
+ f54_query_15 m_f54Query_15;
+ f54_query_16 m_f54Query_16;
+ f54_query_21 m_f54Query_21;
+ f54_query_22 m_f54Query_22;
+ f54_query_23 m_f54Query_23;
+ f54_query_25 m_f54Query_25;
+ f54_query_27 m_f54Query_27;
+ f54_query_29 m_f54Query_29;
+ f54_query_30 m_f54Query_30;
+ f54_query_32 m_f54Query_32;
+ f54_query_33 m_f54Query_33;
+ f54_query_35 m_f54Query_35;
+ f54_query_36 m_f54Query_36;
+ f54_query_38 m_f54Query_38;
+
+ f54_control m_f54Control;
+
+ f55_query m_f55Query;
+
+ f54_report_types m_reportType;
+ unsigned int m_reportSize;
+
+ unsigned char *m_txAssignment;
+ unsigned char *m_rxAssignment;
+ unsigned char m_txAssigned;
+ unsigned char m_rxAssigned;
+
+ unsigned int m_reportBufferSize;
+ unsigned char *m_reportData;
+
+ Display & m_display;
+};
+
+#endif // _F54TEST_H_
diff --git a/f54test/main.cpp b/f54test/main.cpp
new file mode 100644
index 0000000..447fb0a
--- /dev/null
+++ b/f54test/main.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <time.h>
+#include <string>
+#include <sstream>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "hiddevice.h"
+#include "f54test.h"
+#include "display.h"
+
+#define F54TEST_GETOPTS "hd:r:c"
+
+static bool stopRequested;
+
+void printHelp(const char *prog_name)
+{
+ fprintf(stdout, "Usage: %s [OPTIONS]\n", prog_name);
+ fprintf(stdout, "\t-h, --help\tPrint this message\n");
+ fprintf(stdout, "\t-d, --device\thidraw device file associated with the device being tested.\n");
+ fprintf(stdout, "\t-r, --report_type\tReport type.\n");
+ fprintf(stdout, "\t-c, --continuous\tContinuous mode.\n");
+}
+
+int RunF54Test(const char * deviceFile, f54_report_types reportType, bool continuousMode)
+{
+ int rc;
+ HIDDevice rmidevice;
+ Display * display;
+
+ if (continuousMode)
+ {
+ display = new AnsiConsole();
+ }
+ else
+ {
+ display = new Display();
+ }
+
+ display->Clear();
+
+ rc = rmidevice.Open(deviceFile);
+ if (rc)
+ return rc;
+
+ F54Test f54Test(rmidevice, *display);
+
+ rc = f54Test.Prepare(reportType);
+ if (rc)
+ return rc;
+
+ stopRequested = false;
+
+ do {
+ rc = f54Test.Run();
+ }
+ while (continuousMode && !stopRequested);
+
+ rmidevice.Reset();
+
+ rmidevice.Close();
+
+ delete display;
+
+ return rc;
+}
+
+void SignalHandler(int p_signame)
+{
+ stopRequested = true;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int opt;
+ int index;
+ char *deviceName = NULL;
+ static struct option long_options[] = {
+ {"help", 0, NULL, 'h'},
+ {"device", 1, NULL, 'd'},
+ {"report_type", 1, NULL, 'r'},
+ {"continuous", 0, NULL, 'c'},
+ {0, 0, 0, 0},
+ };
+ struct dirent * devDirEntry;
+ DIR * devDir;
+ f54_report_types reportType = F54_16BIT_IMAGE;
+ bool continuousMode = false;
+
+ while ((opt = getopt_long(argc, argv, F54TEST_GETOPTS, long_options, &index)) != -1) {
+ switch (opt) {
+ case 'h':
+ printHelp(argv[0]);
+ return 0;
+ case 'd':
+ deviceName = optarg;
+ break;
+ case 'r':
+ reportType = (f54_report_types)strtol(optarg, NULL, 0);
+ break;
+ case 'c':
+ continuousMode = true;
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ if (continuousMode)
+ {
+ signal(SIGHUP, SignalHandler);
+ signal(SIGINT, SignalHandler);
+ signal(SIGTERM, SignalHandler);
+ }
+
+ if (deviceName) {
+ rc = RunF54Test(deviceName, reportType, continuousMode);
+ if (rc)
+ return rc;
+
+ return rc;
+ } else {
+ char rawDevice[PATH_MAX];
+ char deviceFile[PATH_MAX];
+ bool found = false;
+
+ devDir = opendir("/dev");
+ if (!devDir)
+ return -1;
+
+ while ((devDirEntry = readdir(devDir)) != NULL) {
+ if (strstr(devDirEntry->d_name, "hidraw")) {
+ strncpy(rawDevice, devDirEntry->d_name, PATH_MAX);
+ snprintf(deviceFile, PATH_MAX, "/dev/%s", devDirEntry->d_name);
+ rc = RunF54Test(deviceFile, reportType, continuousMode);
+ if (rc != 0) {
+ continue;
+ } else {
+ found = true;
+ break;
+ }
+ }
+ }
+ closedir(devDir);
+
+ if (!found)
+ return rc;
+ }
+
+ return 0;
+}
diff --git a/f54test/testutil.cpp b/f54test/testutil.cpp
new file mode 100644
index 0000000..6de56b1
--- /dev/null
+++ b/f54test/testutil.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+
+#include "testutil.h"
+
+const char *test_error_str[] = {
+ "success", // TEST_SUCCESS
+ "failed", // TEST_FAIL
+ "timeout", // TEST_FAIL_TIMEOUT
+ "failed to find F01 on device", // TEST_FAIL_NO_FUNCTION_01
+ "failed to find F54 on device", // TEST_FAIL_NO_FUNCTION_54
+ "failed to find F55 on device", // TEST_FAIL_NO_FUNCTION_55
+ "failed to query the basic properties in F01", // TEST_FAIL_QUERY_BASIC_PROPERTIES
+ "failed to read F54 query registers", // TEST_FAIL_READ_F54_QUERIES
+ "failed to read F54 control registers", // TEST_FAIL_READ_F54_CONTROLS
+ "failed to scan the PDT", // TEST_FAIL_SCAN_PDT
+ "failed to read the device status", // TEST_FAIL_READ_DEVICE_STATUS
+ "failed to read F01 control 0 register", // TEST_FAIL_READ_F01_CONTROL_0
+ "failed to write F01 control 0 register", // TEST_FAIL_WRITE_F01_CONTROL_0
+ "timeout waiting for attn", // TEST_FAIL_TIMEOUT_WAITING_FOR_ATTN
+ "invalid parameter", // TEST_FAIL_INVALID_PARAMETER
+ "memory allocation failure", // TEST_FAIL_MEMORY_ALLOCATION
+};
+
+const char * test_err_to_string(int err)
+{
+ return test_error_str[err];
+}
+
+unsigned long extract_long(const unsigned char *data)
+{
+ return (unsigned long)data [0]
+ + (unsigned long)data [1] * 0x100
+ + (unsigned long)data [2] * 0x10000
+ + (unsigned long)data [3] * 0x1000000;
+}
+
+unsigned short extract_short(const unsigned char *data)
+{
+ return (unsigned long)data [0]
+ + (unsigned long)data [1] * 0x100;
+}
+
+const char * StripPath(const char * path, ssize_t size)
+{
+ int i;
+ const char * str;
+
+ for (i = size - 1, str = &path[size - 1]; i > 0; --i, --str)
+ if (path[i - 1] == '/')
+ break;
+
+ return str;
+}
diff --git a/f54test/testutil.h b/f54test/testutil.h
new file mode 100644
index 0000000..3004299
--- /dev/null
+++ b/f54test/testutil.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Satoshi Noguchi
+ * Copyright (C) 2014 Synaptics Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TESTUTIL_H_
+#define _TESTUTIL_H_
+
+enum update_error {
+ TEST_SUCCESS = 0,
+ TEST_FAIL,
+ TEST_FAIL_TIMEOUT,
+ TEST_FAIL_NO_FUNCTION_01,
+ TEST_FAIL_NO_FUNCTION_54,
+ TEST_FAIL_NO_FUNCTION_55,
+ TEST_FAIL_QUERY_BASIC_PROPERTIES,
+ TEST_FAIL_READ_F54_QUERIES,
+ TEST_FAIL_READ_F54_CONTROLS,
+ TEST_FAIL_SCAN_PDT,
+ TEST_FAIL_READ_DEVICE_STATUS,
+ TEST_FAIL_READ_F01_CONTROL_0,
+ TEST_FAIL_WRITE_F01_CONTROL_0,
+ TEST_FAIL_TIMEOUT_WAITING_FOR_ATTN,
+ TEST_FAIL_INVALID_PARAMETER,
+ TEST_FAIL_MEMORY_ALLOCATION,
+};
+
+const char * test_err_to_string(int err);
+
+unsigned long extract_long(const unsigned char *data);
+unsigned short extract_short(const unsigned char *data);
+const char * StripPath(const char * path, ssize_t size);
+
+#endif // _TESTUTIL_H_
diff --git a/rmi4update/main.cpp b/rmi4update/main.cpp
index 764acc7..766d95d 100644
--- a/rmi4update/main.cpp
+++ b/rmi4update/main.cpp
@@ -31,7 +31,7 @@
#include "hiddevice.h"
#include "rmi4update.h"
-#define RMI4UPDATE_GETOPTS "hfd:p"
+#define RMI4UPDATE_GETOPTS "hfd:pl"
void printHelp(const char *prog_name)
{
@@ -40,9 +40,10 @@ void printHelp(const char *prog_name)
fprintf(stdout, "\t-f, --force\tForce updating firmware even it the image provided is older\n\t\t\tthen the current firmware on the device.\n");
fprintf(stdout, "\t-d, --device\thidraw device file associated with the device being updated.\n");
fprintf(stdout, "\t-p, --fw-props\tPrint the firmware properties.\n");
+ fprintf(stdout, "\t-l, --lockdown\tPerform lockdown.\n");
}
-int UpdateDevice(FirmwareImage & image, bool force, const char * deviceFile)
+int UpdateDevice(FirmwareImage & image, bool force, bool performLockdown, const char * deviceFile)
{
HIDDevice rmidevice;
int rc;
@@ -52,7 +53,7 @@ int UpdateDevice(FirmwareImage & image, bool force, const char * deviceFile)
return rc;
RMI4Update update(rmidevice, image);
- rc = update.UpdateFirmware(force);
+ rc = update.UpdateFirmware(force, performLockdown);
if (rc != UPDATE_SUCCESS)
return rc;
@@ -205,11 +206,13 @@ int main(int argc, char **argv)
{"force", 0, NULL, 'f'},
{"device", 1, NULL, 'd'},
{"fw-props", 0, NULL, 'p'},
+ {"lockdown", 0, NULL, 'l'},
{0, 0, 0, 0},
};
struct dirent * devDirEntry;
DIR * devDir;
bool printFirmwareProps = false;
+ bool performLockdown = false;
while ((opt = getopt_long(argc, argv, RMI4UPDATE_GETOPTS, long_options, &index)) != -1) {
switch (opt) {
@@ -225,6 +228,9 @@ int main(int argc, char **argv)
case 'p':
printFirmwareProps = true;
break;
+ case 'l':
+ performLockdown = true;
+ break;
default:
break;
@@ -262,7 +268,7 @@ int main(int argc, char **argv)
if (deviceName) {
char * rawDevice;
- rc = UpdateDevice(image, force, deviceName);
+ rc = UpdateDevice(image, force, performLockdown, deviceName);
if (rc)
return rc;
@@ -283,7 +289,7 @@ int main(int argc, char **argv)
if (strstr(devDirEntry->d_name, "hidraw")) {
strncpy(rawDevice, devDirEntry->d_name, PATH_MAX);
snprintf(deviceFile, PATH_MAX, "/dev/%s", devDirEntry->d_name);
- rc = UpdateDevice(image, force, deviceFile);
+ rc = UpdateDevice(image, force, performLockdown, deviceFile);
if (rc != 0) {
continue;
} else {
diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp
index 9f3d860..f8fe388 100644
--- a/rmi4update/rmi4update.cpp
+++ b/rmi4update/rmi4update.cpp
@@ -84,7 +84,7 @@
*/
#define RMI_F01_CRTL0_NOSLEEP_BIT (1 << 2)
-int RMI4Update::UpdateFirmware(bool force)
+int RMI4Update::UpdateFirmware(bool force, bool performLockdown)
{
struct timespec start;
struct timespec end;
@@ -124,7 +124,7 @@ int RMI4Update::UpdateFirmware(bool force)
}
}
- if (m_unlocked) {
+ if (performLockdown && m_unlocked) {
if (m_firmwareImage.GetLockdownData()) {
fprintf(stdout, "Writing lockdown...\n");
clock_gettime(CLOCK_MONOTONIC, &start);
diff --git a/rmi4update/rmi4update.h b/rmi4update/rmi4update.h
index b59dfc9..ff69ae2 100644
--- a/rmi4update/rmi4update.h
+++ b/rmi4update/rmi4update.h
@@ -29,7 +29,7 @@ public:
RMI4Update(RMIDevice & device, FirmwareImage & firmwareImage) : m_device(device),
m_firmwareImage(firmwareImage)
{}
- int UpdateFirmware(bool force = false);
+ int UpdateFirmware(bool force = false, bool performLockdown = false);
private:
int FindUpdateFunctions();
diff --git a/rmidevice/rmidevice.cpp b/rmidevice/rmidevice.cpp
index 57528be..454998c 100644
--- a/rmidevice/rmidevice.cpp
+++ b/rmidevice/rmidevice.cpp
@@ -255,16 +255,20 @@ void RMIDevice::PrintFunctions()
funcIter->GetQueryBase());
}
-int RMIDevice::ScanPDT(int endFunc)
+int RMIDevice::ScanPDT(int endFunc, int endPage)
{
int rc;
unsigned int page;
+ unsigned int maxPage;
unsigned int addr;
unsigned char entry[RMI_DEVICE_PDT_ENTRY_SIZE];
+ unsigned int interruptCount = 0;
+
+ maxPage = (unsigned int)((endPage < 0) ? RMI_DEVICE_MAX_PAGE : endPage);
m_functionList.clear();
- for (page = 0; page < RMI_DEVICE_MAX_PAGE; ++page) {
+ for (page = 0; page < maxPage; ++page) {
unsigned int page_start = RMI_DEVICE_PAGE_SIZE * page;
unsigned int pdt_start = page_start + RMI_DEVICE_PAGE_SCAN_START;
unsigned int pdt_end = page_start + RMI_DEVICE_PAGE_SCAN_END;
@@ -279,21 +283,24 @@ int RMIDevice::ScanPDT(int endFunc)
return rc;
}
- RMIFunction func(entry);
+ RMIFunction func(entry, page_start, interruptCount);
if (func.GetFunctionNumber() == 0)
break;
m_functionList.push_back(func);
+ interruptCount += func.GetInterruptSourceCount();
found = true;
if (func.GetFunctionNumber() == endFunc)
return 0;
}
- if (!found)
+ if (!found && (endPage < 0))
break;
}
+ m_numInterruptRegs = (interruptCount + 7) / 8;
+
return 0;
}
diff --git a/rmidevice/rmidevice.h b/rmidevice/rmidevice.h
index 5bae8ba..d47ffe1 100644
--- a/rmidevice/rmidevice.h
+++ b/rmidevice/rmidevice.h
@@ -50,7 +50,7 @@ public:
int SetRMIPage(unsigned char page);
- int ScanPDT(int endFunc = 0);
+ int ScanPDT(int endFunc = 0, int endPage = -1);
void PrintProperties();
int Reset();
@@ -61,6 +61,8 @@ public:
void SetBytesPerReadRequest(int bytes) { m_bytesPerReadRequest = bytes; }
+ unsigned int GetNumInterruptRegs() { return m_numInterruptRegs; }
+
protected:
std::vector<RMIFunction> m_functionList;
unsigned char m_manufacturerID;
@@ -91,6 +93,8 @@ protected:
bool m_bCancel;
int m_bytesPerReadRequest;
int m_page;
+
+ unsigned int m_numInterruptRegs;
};
/* Utility Functions */
diff --git a/rmidevice/rmifunction.cpp b/rmidevice/rmifunction.cpp
index a1121a7..3a077e4 100644
--- a/rmidevice/rmifunction.cpp
+++ b/rmidevice/rmifunction.cpp
@@ -27,17 +27,32 @@
#define RMI_FUNCTION_VERSION_MASK 0x60
#define RMI_FUNCTION_INTERRUPT_SOURCES_MASK 0x7
-RMIFunction::RMIFunction(const unsigned char * pdtEntry)
+RMIFunction::RMIFunction(const unsigned char * pdtEntry, unsigned short pageBase, unsigned int interruptCount)
{
+ unsigned char ii;
+ unsigned char interruptOffset;
+
if (pdtEntry) {
- m_queryBase = pdtEntry[RMI_FUNCTION_QUERY_OFFSET];
- m_commandBase = pdtEntry[RMI_FUNCTION_COMMAND_OFFSET];
- m_controlBase = pdtEntry[RMI_FUNCTION_CONTROL_OFFSET];
- m_dataBase = pdtEntry[RMI_FUNCTION_DATA_OFFSET];
+ m_queryBase = pdtEntry[RMI_FUNCTION_QUERY_OFFSET] + pageBase;
+ m_commandBase = pdtEntry[RMI_FUNCTION_COMMAND_OFFSET] + pageBase;
+ m_controlBase = pdtEntry[RMI_FUNCTION_CONTROL_OFFSET] + pageBase;
+ m_dataBase = pdtEntry[RMI_FUNCTION_DATA_OFFSET] + pageBase;
m_interruptSourceCount = pdtEntry[RMI_FUNCTION_INTERRUPT_SOURCES_OFFSET]
& RMI_FUNCTION_INTERRUPT_SOURCES_MASK;
m_functionNumber = pdtEntry[RMI_FUNCTION_NUMBER];
m_functionVersion = (pdtEntry[RMI_FUNCTION_INTERRUPT_SOURCES_OFFSET]
& RMI_FUNCTION_VERSION_MASK) >> 5;
+ if (m_interruptSourceCount > 0)
+ {
+ m_interruptRegNum = (interruptCount + 8) / 8 - 1;
+
+ /* Set an enable bit for each data source */
+ interruptOffset = interruptCount % 8;
+ m_interruptMask = 0;
+ for (ii = interruptOffset;
+ ii < (m_interruptSourceCount + interruptOffset);
+ ii++)
+ m_interruptMask |= 1 << ii;
+ }
}
} \ No newline at end of file
diff --git a/rmidevice/rmifunction.h b/rmidevice/rmifunction.h
index 84a6afd..3257471 100644
--- a/rmidevice/rmifunction.h
+++ b/rmidevice/rmifunction.h
@@ -22,7 +22,7 @@ class RMIFunction
{
public:
RMIFunction() {}
- RMIFunction(const unsigned char * pdtEntry);
+ RMIFunction(const unsigned char * pdtEntry, unsigned short pageBase, unsigned int interruptCount);
unsigned short GetQueryBase() { return m_queryBase; }
unsigned short GetCommandBase() { return m_commandBase; }
unsigned short GetControlBase() { return m_controlBase; }
@@ -30,6 +30,8 @@ public:
unsigned char GetInterruptSourceCount() { return m_interruptSourceCount; }
unsigned char GetFunctionNumber() { return m_functionNumber; }
unsigned char GetFunctionVersion() { return m_functionVersion; }
+ unsigned char GetInterruptRegNum() { return m_interruptRegNum; }
+ unsigned char GetInterruptMask() { return m_interruptMask; }
private:
unsigned short m_queryBase;
@@ -39,6 +41,8 @@ private:
unsigned char m_interruptSourceCount;
unsigned char m_functionNumber;
unsigned char m_functionVersion;
+ unsigned char m_interruptRegNum;
+ unsigned char m_interruptMask;
};
#endif // _RMIFUNCTION_H_ \ No newline at end of file