//****************************************************************************** /// \brief Get debug message bytes /// \param mxt Device context /// \param buf Pointer to buffer /// \param buflen Length of buffer /// \param count length of message in bytes /// \return #mxt_rc int sysfs_get_msg_bytes_v2(struct mxt_device *mxt, unsigned char *buf, size_t buflen, int *count) { uint16_t t5_size; if (!mxt->sysfs.debug_v2_msg_buf) return MXT_INTERNAL_ERROR; t5_size = mxt_get_object_size(mxt, GEN_MESSAGEPROCESSOR_T5) - 1; if (buflen < t5_size) return MXT_ERROR_NO_MEM; if (mxt->sysfs.debug_v2_msg_ptr > mxt->sysfs.debug_v2_msg_count) return MXT_INTERNAL_ERROR; memcpy(buf, mxt->sysfs.debug_v2_msg_buf + mxt->sysfs.debug_v2_msg_ptr * t5_size, t5_size); mxt->sysfs.debug_v2_msg_ptr++; *count = t5_size; return MXT_SUCCESS; }
//****************************************************************************** /// \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; }
//****************************************************************************** /// \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; }
//****************************************************************************** /// \brief Get messages (V2 interface) /// \param mxt Device context /// \param count Number of messages retrieved /// \return #mxt_rc int sysfs_get_msgs_v2(struct mxt_device *mxt, int *count) { int num_bytes; uint16_t t5_size; char *filename; struct stat filestat; int ret; int fd; sysfs_reopen_notify_fd(mxt); filename = make_path(mxt, "debug_msg"); ret = stat(filename, &filestat); if (ret < 0) { mxt_err(mxt->ctx, "Could not stat %s, error %s (%d)", filename, strerror(errno), errno); return mxt_errno_to_rc(errno); } mxt->sysfs.debug_v2_size = filestat.st_size; if (mxt->sysfs.debug_v2_msg_buf) { free(mxt->sysfs.debug_v2_msg_buf); mxt->sysfs.debug_v2_msg_buf = NULL; } mxt->sysfs.debug_v2_msg_buf = calloc(mxt->sysfs.debug_v2_size, sizeof(uint8_t)); fd = open(filename, O_RDWR); if (fd < 0) { mxt_err(mxt->ctx, "Could not open %s, error %s (%d)", filename, strerror(errno), errno); ret = mxt_errno_to_rc(errno); goto close; } t5_size = mxt_get_object_size(mxt, GEN_MESSAGEPROCESSOR_T5) - 1; num_bytes = read(fd, mxt->sysfs.debug_v2_msg_buf, mxt->sysfs.debug_v2_size); if (num_bytes < 0) { mxt_err(mxt->ctx, "read error %s (%d)", strerror(errno), errno); ret = mxt_errno_to_rc(errno); goto close; } mxt->sysfs.debug_v2_msg_count = num_bytes / t5_size; mxt->sysfs.debug_v2_msg_ptr = 0; ret = MXT_SUCCESS; *count = mxt->sysfs.debug_v2_msg_count; mxt_verb(mxt->ctx, "count = %d", mxt->sysfs.debug_v2_msg_count); close: close(fd); return ret; }
//****************************************************************************** /// \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; }