Example #1
0
//******************************************************************************
/// \brief Retrieve a single page of diagnostic data
/// \return #mxt_rc
static int mxt_get_t37_page(struct t37_ctx *ctx)
{
  int failures;
  int ret;
  uint8_t read_command = 1;
  uint8_t page_up_cmd = PAGE_UP;

  if (ctx->pass == 0 && ctx->page == 0) {
    mxt_dbg(ctx->lc, "Writing mode command %02X", ctx->mode);
    ret = mxt_write_register(ctx->mxt, &ctx->mode, ctx->diag_cmd_addr, 1);
    if (ret)
      return ret;
  } else {
    ret = mxt_write_register(ctx->mxt, &page_up_cmd, ctx->diag_cmd_addr, 1);
    if (ret)
      return ret;
  }

  /* Read back diagnostic register in T6 command processor until it has been
   * cleared. This means that the chip has actioned the command */
  failures = 0;

  while (read_command) {
    usleep(500);
    ret = mxt_read_register(ctx->mxt, &read_command, ctx->diag_cmd_addr, 1);
    if (ret) {
      mxt_err(ctx->lc, "Failed to read the status of diagnostic mode command");
      return ret;
    }

    if (read_command) {
      failures++;

      if (failures > 500) {
        mxt_err(ctx->lc, "Timeout waiting for command to be actioned");
        return MXT_ERROR_TIMEOUT;
      }
    }
  }

  ret = mxt_read_register(ctx->mxt, (uint8_t *)ctx->t37_buf,
                          ctx->t37_addr, ctx->t37_size);
  if (ret) {
    mxt_err(ctx->lc, "Failed to read page");
    return ret;
  }

  if (ctx->t37_buf->mode != ctx->mode) {
    mxt_err(ctx->lc, "Bad mode in diagnostic data read");
    return MXT_ERROR_UNEXPECTED_DEVICE_STATE;
  }

  if (ctx->t37_buf->page != (ctx->pages_per_pass * ctx->pass + ctx->page)) {
    mxt_err(ctx->lc, "Bad page in diagnostic data read");
    return MXT_ERROR_UNEXPECTED_DEVICE_STATE;
  }

  return MXT_SUCCESS;
}
Example #2
0
/*!
 * @brief  Reads the information block from the chip.
 * @return #mxt_rc
 */
int mxt_read_info_block(struct mxt_device *mxt)
{
  int ret;

  /* Read the ID Information from the chip */
  uint8_t *info_blk = (uint8_t *)calloc(1, sizeof(struct mxt_id_info));
  if (info_blk == NULL)
  {
    mxt_err(mxt->ctx, "Memory allocation failure");
    return MXT_ERROR_NO_MEM;
  }

  ret = mxt_read_register(mxt, info_blk, 0, sizeof(struct mxt_id_info));
  if (ret)
  {
    mxt_err(mxt->ctx, "Failed to read ID information");
    return ret;
  }

  /* Determine the number of bytes for checksum calculation */
  int num_objects = ((struct mxt_id_info*) info_blk)->num_objects;
  size_t crc_area_size = sizeof(struct mxt_id_info)
                         + num_objects * sizeof(struct mxt_object);

  /* Allocate space to read Information Block AND Checksum from the chip */
  size_t info_block_size = crc_area_size + sizeof(struct mxt_raw_crc);

  info_blk = (uint8_t *)realloc(info_blk, info_block_size);
  if (info_blk == NULL)
  {
    mxt_err(mxt->ctx, "Memory allocation failure");
    return MXT_ERROR_NO_MEM;
  }

  /* Read the entire Information Block from the chip */
  ret = mxt_read_register(mxt, info_blk, 0, info_block_size);
  if (ret)
  {
    mxt_err(mxt->ctx, "Failed to read Information Block");
    return ret;
  }

  /* Update pointers in device structure */
  mxt->info.raw_info = info_blk;
  mxt->info.id = (struct mxt_id_info*) info_blk;
  mxt->info.objects = (struct mxt_object*)(info_blk + sizeof(struct mxt_id_info));

  mxt->info.crc = convert_crc((struct mxt_raw_crc*) (info_blk + crc_area_size));

  /* Calculate and compare Information Block Checksum */
  ret = calculate_crc(mxt, mxt->info.crc, info_blk, crc_area_size);
  if (ret)
    return ret;

  return MXT_SUCCESS;
}
Example #3
0
//******************************************************************************
/// \brief Print T25 limits for each enabled touch object
static void print_t25_limits(struct mxt_device *mxt, uint16_t t25_addr)
{
   int i;
   struct mxt_object obj;
   int touch_object = 0;
   uint8_t buf[4];
   uint16_t upsiglim;
   uint16_t losiglim;
   int instance;

   for (i = 0; i < mxt->info.id->num_objects; i++)
   {
      obj = mxt->info.objects[i];

      switch (obj.type)
      {
      case TOUCH_MULTITOUCHSCREEN_T9:
      case TOUCH_SINGLETOUCHSCREEN_T10:
      case TOUCH_XSLIDER_T11:
      case TOUCH_YSLIDER_T12:
      case TOUCH_XWHEEL_T13:
      case TOUCH_YWHEEL_T14:
      case TOUCH_KEYARRAY_T15:
      case TOUCH_PROXIMITY_T23:
      case TOUCH_KEYSET_T31:
      case TOUCH_XSLIDERSET_T32:
         for (instance = 0; (instance < MXT_INSTANCES(obj)); instance++)
         {
            mxt_read_register(mxt, (uint8_t *)&buf, mxt_get_start_position(obj, instance), 1);

            mxt_info(mxt->ctx, "%s[%d] %s",
                   mxt_get_object_name(obj.type),
                   instance,
                   buf[0] & 0x01 ? "enabled":"disabled");

            mxt_read_register(mxt, (uint8_t *)&buf,
               t25_addr + 2 + touch_object * 4, 4);

            upsiglim = (uint16_t)((buf[1] << 8u) | buf[0]);
            losiglim = (uint16_t)((buf[3] << 8u) | buf[2]);

            mxt_info(mxt->ctx, "  UPSIGLIM:%d", upsiglim);
            mxt_info(mxt->ctx, "  LOSIGLIM:%d", losiglim);

            touch_object++;
         }
         break;
      default:
         break;
      }
   }
   
}
Example #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;
  }
}
Example #5
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;
}
Example #6
0
//******************************************************************************
/// \brief Handle bridge read
/// \return #mxt_rc
static int bridge_rea_cmd(struct mxt_device *mxt, int sockfd,
                          uint16_t address, uint16_t count)
{
  int ret;
  uint8_t *databuf;
  char *response;
  const char * const PREFIX = "RRP ";
  size_t response_len;
  int i;

  databuf = calloc(count, sizeof(uint8_t));
  if (!databuf) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    return MXT_ERROR_NO_MEM;
  }

  /* Allow for newline/null byte */
  response_len = strlen(PREFIX) + count*2 + 1;
  response = calloc(response_len, sizeof(uint8_t));
  if (!response) {
    mxt_err(mxt->ctx, "Failed to allocate memory");
    ret = MXT_ERROR_NO_MEM;
    goto free_databuf;
  }

  strcpy(response, PREFIX);
  ret = mxt_read_register(mxt, databuf, address, count);
  if (ret) {
    mxt_warn(mxt->ctx, "RRP ERR");
    strcpy(response + strlen(PREFIX), "ERR\n");
    response_len = strlen(response);
  } else {
    for (i = 0; i < count; i++) {
      sprintf(response + strlen(PREFIX) + i*2, "%02X", databuf[i]);
    }
    mxt_info(mxt->ctx, "%s", response);
    response[response_len - 1] = '\n';
  }

  ret = write(sockfd, response, response_len);
  if (ret < 0) {
    mxt_err(mxt->ctx, "Socket write error: %s (%d)", strerror(errno), errno);
    ret = mxt_errno_to_rc(errno);
    goto free;
  }

  ret = MXT_SUCCESS;

free:
  free(response);
free_databuf:
  free(databuf);
  return ret;
}
Example #7
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;
}