/*
* 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;
}