//****************************************************************************** /// \brief Handle messages from the self test object /// \return #mxt_rc static int self_test_handle_messages(struct mxt_device *mxt) { bool done = false; int count, i; time_t now; time_t start_time = time(NULL); static const uint8_t TIMEOUT = 10; // seconds uint8_t buf[10]; int len; unsigned int object_type; int ret; while (!done) { mxt_msg_wait(mxt, 100); now = time(NULL); if ((now - start_time) > TIMEOUT) { mxt_err(mxt->ctx, "Timeout"); return MXT_ERROR_TIMEOUT; } ret = mxt_get_msg_count(mxt, &count); if (ret) return ret; if (count > 0) { for (i = 0; i < count; i++) { ret = mxt_get_msg_bytes(mxt, buf, sizeof(buf), &len); if (ret) return ret; if (len > 0) { object_type = mxt_report_id_to_type(mxt, buf[0]); mxt_verb(mxt->ctx, "Received message from T%u", object_type); if (object_type == SPT_SELFTEST_T25) { switch (buf[1]) { case SELF_TEST_ALL: mxt_info(mxt->ctx, "PASS: All tests passed"); ret = MXT_SUCCESS; break; case SELF_TEST_INVALID: mxt_err(mxt->ctx, "FAIL: Invalid test command"); ret = MXT_ERROR_NOT_SUPPORTED; break; case SELF_TEST_TIMEOUT: mxt_err(mxt->ctx, "FAIL: Test timeout"); ret = MXT_ERROR_TIMEOUT; break; case SELF_TEST_ANALOG: mxt_err(mxt->ctx, "FAIL: AVdd Analog power is not present"); ret = MXT_ERROR_SELF_TEST_ANALOG; break; case SELF_TEST_PIN_FAULT: mxt_err(mxt->ctx, "FAIL: Pin fault"); ret = MXT_ERROR_SELF_TEST_PIN_FAULT; break; case SELF_TEST_PIN_FAULT_2: mxt_err(mxt->ctx, "FAIL: Pin fault 2"); ret = MXT_ERROR_SELF_TEST_PIN_FAULT; break; case SELF_TEST_AND_GATE: mxt_err(mxt->ctx, "FAIL: AND Gate Fault"); ret = MXT_ERROR_SELF_TEST_AND_GATE; break; case SELF_TEST_SIGNAL_LIMIT: mxt_err(mxt->ctx, "FAIL: Signal limit fault"); ret = MXT_ERROR_SELF_TEST_SIGNAL_LIMIT; break; case SELF_TEST_GAIN: mxt_err(mxt->ctx, "FAIL: Gain error"); ret = MXT_ERROR_SELF_TEST_GAIN; break; default: mxt_err(mxt->ctx, "Unrecognised status %02X", buf[1]); ret = MXT_ERROR_UNEXPECTED_DEVICE_STATE; break; } done = true; } } } } } return ret; }
//****************************************************************************** /// \brief Run self cap tuning procedure without updating the config /// checksum /// \return #mxt_rc int mxt_self_cap_tune(struct mxt_device *mxt, mxt_app_cmd cmd) { int ret; uint16_t t6_addr; uint16_t t109_addr; uint8_t backupnv_value; uint8_t t109_command; mxt_msg_reset(mxt); // Enable self test object & reporting t6_addr = mxt_get_object_address(mxt, GEN_COMMANDPROCESSOR_T6, 0); if (t6_addr == OBJECT_NOT_FOUND) return MXT_ERROR_OBJECT_NOT_FOUND; t109_addr = mxt_get_object_address(mxt, SPT_SELFCAPGLOBALCONFIG_T109, 0); if (t109_addr == OBJECT_NOT_FOUND) return MXT_ERROR_OBJECT_NOT_FOUND; mxt_info(mxt->ctx, "Stopping T70"); backupnv_value = 0x33; ret = mxt_write_register(mxt, &backupnv_value, t6_addr + MXT_T6_BACKUPNV_OFFSET, 1); if (ret) return ret; // Wait for backup operation to complete (otherwise T109 report may be missed) mxt_msg_wait(mxt, 100); mxt_info(mxt->ctx, "Tuning"); t109_command = T109_CMD_TUNE; mxt_info(mxt->ctx, "Writing %u to T109 CMD register", cmd); ret = mxt_write_register(mxt, &t109_command, t109_addr + T109_CMD_OFFSET, 1); if (ret) return ret; ret = mxt_read_messages(mxt, T109_TIMEOUT, &t109_command, mxt_self_cap_command, (int *)&mxt_sigint_rx); if (ret) return ret; switch (cmd) { case CMD_SELF_CAP_TUNE_CONFIG: mxt_info(mxt->ctx, "Store to Config"); t109_command = T109_CMD_STORE_TO_CONFIG_RAM; break; default: case CMD_SELF_CAP_TUNE_NVRAM: mxt_info(mxt->ctx, "Store to NVRAM"); t109_command = T109_CMD_STORE_TO_NVM; break; } mxt_info(mxt->ctx, "Writing %u to T109 CMD register", cmd); ret = mxt_write_register(mxt, &t109_command, t109_addr + T109_CMD_OFFSET, 1); if (ret) return ret; ret = mxt_read_messages(mxt, 100, (void *) &t109_command, mxt_self_cap_command, (int *)&mxt_sigint_rx); if (ret) return ret; mxt_info(mxt->ctx, "Saving configuration"); ret = mxt_backup_config(mxt, BACKUPNV_COMMAND); if (ret) return ret; ret = mxt_reset_chip(mxt, false); if (ret) return ret; return MXT_SUCCESS; }