Esempio n. 1
0
//******************************************************************************
/// \brief Disable noise suppression objects
static void disable_noise_suppression(struct mxt_device *mxt)
{
   uint16_t addr;
   uint8_t disable = 0;

   addr = mxt_get_object_address(mxt, PROCG_NOISESUPPRESSION_T22, 0);
   if (addr != OBJECT_NOT_FOUND)
   {
      mxt_write_register(mxt, &disable, addr, 1);
   }

   addr = mxt_get_object_address(mxt, PROCG_NOISESUPPRESSION_T48, 0);
   if (addr != OBJECT_NOT_FOUND)
   {
      mxt_write_register(mxt, &disable, addr, 1);
   }

   addr = mxt_get_object_address(mxt, PROCG_NOISESUPPRESSION_T54, 0);
   if (addr != OBJECT_NOT_FOUND)
   {
      mxt_write_register(mxt, &disable, addr, 1);
   }

   addr = mxt_get_object_address(mxt, PROCG_NOISESUPPRESSION_T62, 0);
   if (addr != OBJECT_NOT_FOUND)
   {
      mxt_write_register(mxt, &disable, addr, 1);
   }
}
Esempio n. 2
0
//******************************************************************************
/// \brief Retrieve and store object information for debug data operation
/// \return #mxt_rc
static int get_objects_addr(struct t37_ctx *ctx)
{
  int t6_addr;

  /* Obtain command processor's address */
  t6_addr = mxt_get_object_address(ctx->mxt, GEN_COMMANDPROCESSOR_T6, 0);
  if (t6_addr == OBJECT_NOT_FOUND) return MXT_ERROR_OBJECT_NOT_FOUND;

  /* T37 commands address */
  ctx->diag_cmd_addr = t6_addr + MXT_T6_DIAGNOSTIC_OFFSET;

  /* Obtain Debug Diagnostic object's address */
  ctx->t37_addr = mxt_get_object_address(ctx->mxt, DEBUG_DIAGNOSTIC_T37, 0);
  if (ctx->t37_addr == OBJECT_NOT_FOUND) return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Obtain Debug Diagnostic object's size */
  ctx->t37_size = mxt_get_object_size(ctx->mxt, DEBUG_DIAGNOSTIC_T37);
  if (ctx->t37_size == OBJECT_NOT_FOUND) return MXT_ERROR_OBJECT_NOT_FOUND;

  ctx->t111_instances = mxt_get_object_instances(ctx->mxt,
                        SPT_SELFCAPCONFIG_T111);

  ctx->t107_instances = mxt_get_object_instances(ctx->mxt,
                        PROCI_ACTIVESTYLUS_T107);

  return MXT_SUCCESS;
}
Esempio n. 3
0
//******************************************************************************
/// \brief  Get next MSG into byte buffer
/// \return #mxt_rc
int t44_get_msg_bytes(struct mxt_device *mxt, unsigned char *buf,
                      size_t buflen, int *count)
{
  int ret;
  uint16_t addr;
  uint16_t size;

  addr = mxt_get_object_address(mxt, GEN_MESSAGEPROCESSOR_T5, 0);
  if (addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Do not read CRC byte */
  size = mxt_get_object_size(mxt, GEN_MESSAGEPROCESSOR_T5) - 1;
  if (size > buflen)
  {
    mxt_err(mxt->ctx, "Buffer too small!");
    return MXT_ERROR_NO_MEM;
  }

  ret = mxt_read_register(mxt, buf, addr, size);
  if (ret)
    return ret;

  /* Check for invalid message */
  if (buf[0] == 255u)
  {
    mxt_verb(mxt->ctx, "Invalid message");
    return MXT_ERROR_NO_MESSAGE;
  }

  *count = size;
  return MXT_SUCCESS;
}
Esempio n. 4
0
//******************************************************************************
/// \brief Check chip is not in deep sleep
/// \return #mxt_rc
static int mxt_t68_check_power_cfg(struct t68_ctx *ctx)
{
  uint16_t t7_addr;
  uint8_t buf[2];
  int ret;

  /* Skip if object not present */
  t7_addr = mxt_get_object_address(ctx->mxt, GEN_POWERCONFIG_T7, 0);
  if (t7_addr == OBJECT_NOT_FOUND)
    return MXT_SUCCESS;

  ret = mxt_read_register(ctx->mxt, &buf[0], t7_addr, sizeof(buf));
  if (ret)
    return ret;

  mxt_verb(ctx->lc, "T7 IDLEACQINT=%u ACTVACQINT=%u", buf[0], buf[1]);

  if ((buf[0] == 0) || (buf[1] == 0)) {
    mxt_err(ctx->lc, "Warning: The T7 power configuration object shows that the chip "
            "is in deep sleep, and so will not process T68 serial data "
            "commands. Please set the T7 power configuration idle acquisition "
            "interval to a non-zero value and try again.");

    return MXT_ERROR_UNEXPECTED_DEVICE_STATE;
  } else {
    return MXT_SUCCESS;
  }
}
Esempio n. 5
0
//******************************************************************************
/// \brief  Perform fallback reset
/// \return #mxt_rc
static int mxt_send_reset_command(struct mxt_device *mxt, bool bootloader_mode)
{
  int ret;
  uint16_t t6_addr;
  unsigned char write_value = RESET_COMMAND;

  /* Obtain command processor's address */
  t6_addr = mxt_get_object_address(mxt, GEN_COMMANDPROCESSOR_T6, 0);
  if (t6_addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* The value written determines which mode the chip will boot into */
  if (bootloader_mode) {
    mxt_info(mxt->ctx, "Resetting in bootloader mode");
    write_value = BOOTLOADER_COMMAND;
  } else {
    mxt_info(mxt->ctx, "Sending reset command");
  }

  /* Write to command processor register to perform command */
  ret = mxt_write_register
        (
          mxt, &write_value, t6_addr + MXT_T6_RESET_OFFSET, 1
        );

  return ret;
}
Esempio n. 6
0
//******************************************************************************
/// \brief  Get number of messages
/// \return #mxt_rc
int t44_get_msg_count(struct mxt_device *mxt, int *count_out)
{
  uint16_t addr;
  int ret;
  uint8_t count;

  addr = mxt_get_object_address(mxt, SPT_MESSAGECOUNT_T44, 0);
  if (addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Get T44 count */
  ret = mxt_read_register(mxt, &count, addr, 1);
  if (ret)
    return ret;

  *count_out = count;
  return MXT_SUCCESS;
}
Esempio n. 7
0
//******************************************************************************
/// \brief Run self test
int run_self_tests(struct mxt_device *mxt, uint8_t cmd)
{
   uint16_t t25_addr;
   uint8_t enable = 3;

   mxt_msg_reset(mxt);

   // Enable self test object & reporting
   t25_addr = mxt_get_object_address(mxt, SPT_SELFTEST_T25, 0);
   mxt_info(mxt->ctx, "Enabling self test object");
   mxt_write_register(mxt, &enable, t25_addr, 1);

   mxt_info(mxt->ctx, "Disabling noise suppression");
   disable_noise_suppression(mxt);

   print_t25_limits(mxt, t25_addr);

   mxt_info(mxt->ctx, "Running tests");
   mxt_write_register(mxt, &cmd, t25_addr + 1, 1);

   return self_test_handle_messages(mxt);
}
Esempio n. 8
0
//******************************************************************************
/// \brief  Backup configuration settings to non-volatile memory
/// \return #mxt_rc
int mxt_backup_config(struct mxt_device *mxt, uint8_t backup_command)
{
  int ret;
  uint16_t t6_addr;

  /* Obtain command processor's address */
  t6_addr = mxt_get_object_address(mxt, GEN_COMMANDPROCESSOR_T6, 0);
  if (t6_addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Write to command processor register to perform command */
  ret = mxt_write_register
        (
          mxt, &backup_command, t6_addr + MXT_T6_BACKUPNV_OFFSET, 1
        );

  if (ret == MXT_SUCCESS)
    mxt_info(mxt->ctx, "Backed up settings to the non-volatile memory");
  else
    mxt_err(mxt->ctx, "Failed to back up settings");

  return ret;
}
Esempio n. 9
0
//******************************************************************************
/// \brief  Issue REPORTALL command to device
/// \return #mxt_rc
int mxt_report_all(struct mxt_device *mxt)
{
  int ret;
  uint16_t t6_addr;
  const uint8_t report_all_cmd = 0xff;

  /* Obtain command processor's address */
  t6_addr = mxt_get_object_address(mxt, GEN_COMMANDPROCESSOR_T6, 0);
  if (t6_addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Write to command processor register to perform command */
  ret = mxt_write_register
        (
          mxt, &report_all_cmd, t6_addr + MXT_T6_REPORTALL_OFFSET, 1
        );

  if (ret == MXT_SUCCESS)
    mxt_info(mxt->ctx, "REPORTALL command issued");
  else
    mxt_err(mxt->ctx, "Failed to issue REPORTALL command");

  return ret;
}
Esempio n. 10
0
//******************************************************************************
/// \brief  Calibrate maxtouch chip
/// \return 0 = success, negative = fail
int mxt_calibrate_chip(struct mxt_device *mxt)
{
  int ret;
  uint16_t t6_addr;
  unsigned char write_value = CALIBRATE_COMMAND;

  /* Obtain command processor's address */
  t6_addr = mxt_get_object_address(mxt, GEN_COMMANDPROCESSOR_T6, 0);
  if (t6_addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  mxt_flush_msgs(mxt);

  /* Write to command processor register to perform command */
  ret = mxt_write_register(mxt, &write_value, t6_addr + MXT_T6_CALIBRATE_OFFSET, 1);
  if (ret == 0) {
    mxt_info(mxt->ctx, "Sent calibration command");
  } else {
    mxt_err(mxt->ctx, "Failed to send calibration command");
  }

  int state = 0;
  int flag = false;

  ret = mxt_read_messages(mxt, MXT_CALIBRATE_TIMEOUT, &state,
                          handle_calibrate_msg, &flag);
  if (ret == MXT_ERROR_TIMEOUT) {
    mxt_warn(mxt->ctx, "WARN: timed out waiting for calibrate status");
    return MXT_SUCCESS;
  } else if (ret) {
    mxt_err(mxt->ctx, "FAIL: device calibration failed");
    return ret;
  }

  return MXT_SUCCESS;
}
Esempio n. 11
0
/**
 * \brief Set maXTouch configuration
 *
 * This function writes a set of predefined, optimal maXTouch configuration data
 * to the mXT143E Xplained.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_init(struct mxt_device *device)
{
	enum status_code status;
	UNUSED(status);

	/* T8 configuration object data */
	uint8_t t8_object[] = {
		0x10, 0x05, 0x0a, 0x14, 0x64, 0x00, 0x05,
		0x0a, 0x00, 0x00,
	};

	/* T9 configuration object data */
	uint8_t t9_object[] = {
		0x8f, 0x00, 0x00, 0x0d, 0x0b, 0x00, 0x21,
		0x3c, 0x0f, 0x00, 0x32, 0x01, 0x01, 0x00,
		0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x1c, 0x1c, 0x37, 0x37, 0x8f, 0x50,
		0xcf, 0x6e, 0x00, 0x02, 0x2f, 0x2c, 0x00
	};

	/* T48 configuration object data */
	uint8_t t48_object[] = {
		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00
	};

	/* TWI configuration */
	twi_master_options_t twi_opt = {
		.speed = MXT_TWI_SPEED,
		.chip  = MAXTOUCH_TWI_ADDRESS,
	};

	status = twi_master_setup(TWI_INTERFACE, &twi_opt);
	Assert(status == STATUS_OK);

	/* Initialize the maXTouch device */
	status = mxt_init_device(device, TWI_INTERFACE,
			MAXTOUCH_TWI_ADDRESS, MXT143E_XPLAINED_CHG);
	Assert(status == STATUS_OK);

	/* Issue soft reset of maXTouch device by writing a non-zero value to
	 * the reset register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_RESET, 0x01);

	/* Wait for the reset of the device to complete */
	delay_ms(MXT_RESET_TIME);

	/* Write data to configuration registers in T7 configuration object */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 0, 0xff);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 1, 0xff);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 2, 0x32);

	/* Write predefined configuration data to configuration objects */
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_GEN_ACQUISITIONCONFIG_T8, 0), &t8_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_TOUCH_MULTITOUCHSCREEN_T9, 0), &t9_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_PROCG_TOUCHSUPPRESSION_T48, 0), &t48_object);

	/* Issue recalibration command to maXTouch device by writing a non-zero
	 * value to the calibrate register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_CALIBRATE, 0x01);
}
Esempio n. 12
0
//******************************************************************************
/// \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;
}
Esempio n. 13
0
/**
 * \brief Set maXTouch configuration
 *
 * This function writes a set of predefined, optimal maXTouch configuration data
 * to the maXTouch Xplained Pro.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_init(struct mxt_device *device)
{
	enum status_code status;

	/* T8 configuration object data */
	uint8_t t8_object[] = {
		0x0d, 0x00, 0x05, 0x0a, 0x4b, 0x00, 0x00,
		0x00, 0x32, 0x19
	};

	/* T9 configuration object data */
	uint8_t t9_object[] = {
		0x8B, 0x00, 0x00, 0x0E, 0x08, 0x00, 0x80,
		0x32, 0x05, 0x02, 0x0A, 0x03, 0x03, 0x20,
		0x02, 0x0F, 0x0F, 0x0A, 0x00, 0x00, 0x00,
		0x00, 0x18, 0x18, 0x20, 0x20, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x02,
		0x02
	};

	/* T46 configuration object data */
	uint8_t t46_object[] = {
		0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x03,
		0x00, 0x00
	};
	
	/* T56 configuration object data */
	uint8_t t56_object[] = {
		0x02, 0x00, 0x01, 0x18, 0x1E, 0x1E, 0x1E,
		0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
		0x1E, 0x1E, 0x1E, 0x1E, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00
	};

	/* TWI configuration */
	twihs_master_options_t twi_opt = {
		.speed = MXT_TWI_SPEED,
		.chip  = MAXTOUCH_TWI_ADDRESS,
	};

	status = (enum status_code)twihs_master_setup(MAXTOUCH_TWI_INTERFACE, &twi_opt);
	Assert(status == STATUS_OK);

	/* Initialize the maXTouch device */
	status = mxt_init_device(device, MAXTOUCH_TWI_INTERFACE,
			MAXTOUCH_TWI_ADDRESS, MAXTOUCH_XPRO_CHG_PIO);
	Assert(status == STATUS_OK);

	/* Issue soft reset of maXTouch device by writing a non-zero value to
	 * the reset register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_RESET, 0x01);

	/* Wait for the reset of the device to complete */
	delay_ms(MXT_RESET_TIME);

	/* Write data to configuration registers in T7 configuration object */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 0, 0x20);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 1, 0x10);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 2, 0x4b);
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_POWERCONFIG_T7, 0) + 3, 0x84);

	/* Write predefined configuration data to configuration objects */
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_GEN_ACQUISITIONCONFIG_T8, 0), &t8_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_TOUCH_MULTITOUCHSCREEN_T9, 0), &t9_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_SPT_CTE_CONFIGURATION_T46, 0), &t46_object);
	mxt_write_config_object(device, mxt_get_object_address(device,
			MXT_PROCI_SHIELDLESS_T56, 0), &t56_object);

	/* Issue recalibration command to maXTouch device by writing a non-zero
	 * value to the calibrate register */
	mxt_write_config_reg(device, mxt_get_object_address(device,
			MXT_GEN_COMMANDPROCESSOR_T6, 0)
			+ MXT_GEN_COMMANDPROCESSOR_CALIBRATE, 0x01);
}
Esempio n. 14
0
//******************************************************************************
/// \brief Upload file to T68 Serial Data Object
/// \return #mxt_rc
int mxt_serial_data_upload(struct mxt_device *mxt, const char *filename, uint16_t datatype)
{
  int ret;
  struct t68_ctx ctx;

  ctx.mxt = mxt;
  ctx.lc = mxt->ctx;

  ret = mxt_msg_reset(mxt);
  if (ret)
    return ret;

  mxt_info(ctx.lc, "Checking T7 Power Config");
  ret = mxt_t68_check_power_cfg(&ctx);
  if (ret)
    return ret;

  /* Check for existence of T68 object */
  ctx.t68_addr = mxt_get_object_address(mxt, SERIAL_DATA_COMMAND_T68, 0);
  if (ctx.t68_addr == OBJECT_NOT_FOUND)
    return MXT_ERROR_OBJECT_NOT_FOUND;

  /* Calculate position of CMD register */
  ctx.t68_size = mxt_get_object_size(mxt, SERIAL_DATA_COMMAND_T68);
  ctx.t68_cmd_addr = ctx.t68_addr + ctx.t68_size - 3;

  /* Calculate frame size */
  ctx.t68_data_size = ctx.t68_size - 9;

  /* Set datatype from command line */
  ctx.t68_datatype = datatype;

  /* Read input file */
  ctx.filename = filename;
  ret = mxt_t68_load_file(&ctx);
  if (ret)
    return ret;

  ret = mxt_t68_enable(&ctx);
  if (ret)
    goto release;

  ret = mxt_t68_zero_data(&ctx);
  if (ret)
    goto release;

  ret = mxt_t68_write_length(&ctx, 0);
  if (ret)
    goto release;

  mxt_info(ctx.lc, "Configuring T68");
  ret = mxt_t68_write_datatype(&ctx);
  if (ret)
    goto release;

  mxt_info(ctx.lc, "Sending data");
  ret = mxt_t68_send_frames(&ctx);
  if (ret) {
    mxt_err(ctx.lc, "Error sending data");
    goto release;
  }

  mxt_info(ctx.lc, "Done");
  ret = MXT_SUCCESS;

release:
  mxt_buf_free(&ctx.buf);
  return ret;
}