/* * Atmel mxt probably mxt1188s-a or mxt1664s-a or mxt3432s or mxt143e * I think its the mxt143e * * URL for original source material: * http://www.atmel.com/products/touchsolutions/touchscreens/unlimited_touch.aspx * GIT for original source material: * git://github.com/atmel-maxtouch/obp-utils.git * * cc obp-utils.c test_atmel.c -o /tmp/test -I/usr/src/sys/ * * kldload smb before running test program to get /dev/smb* */ #include #include #include #include #include #include #include #include #include #include #include "obp-utils.h" static const char * mxt_gettypestring(int type) { static const struct mxt_strinfo strinfo[] = { MXT_INIT_STRINGS }; int i; for (i = 0; i < sizeof(strinfo) / sizeof(strinfo[0]); ++i) { if (strinfo[i].type == type) return(strinfo[i].id); } return("unknown"); } struct mxt_object * mxt_findobject(struct mxt_rollup *rup, int type) { int i; for (i = 0; i < rup->nobjs; ++i) { if (rup->objs[i].type == type) return(&rup->objs[i]); } return NULL; } static int mxt_read_reg(int fd, uint16_t reg, void *rbuf, int bytes) { struct smbcmd cmd; uint8_t wbuf[2]; int r; bzero(&cmd, sizeof(cmd)); wbuf[0] = reg & 255; wbuf[1] = reg >> 8; cmd.slave = 0; cmd.rbuf = rbuf; cmd.wbuf = wbuf; cmd.wcount = 2; cmd.rcount = bytes; cmd.op = SMB_TRANS_NOCNT | SMB_TRANS_NOCMD | SMB_TRANS_7BIT; r = ioctl(fd, SMB_TRANS, &cmd); if (r == 0) { return cmd.rcount; } else { printf("status r = %d slave 0x%02x\n", r, cmd.slave); return -1; } } static int mxt_write_reg_buf(int fd, uint16_t reg, void *xbuf, int bytes) { struct smbcmd cmd; uint8_t wbuf[256]; int r; assert(bytes < sizeof(wbuf) - 2); wbuf[0] = reg & 0xff; wbuf[1] = reg >> 8; bcopy(xbuf, wbuf + 2, bytes); cmd.slave = 0; cmd.rbuf = NULL; cmd.wbuf = wbuf; cmd.wcount = bytes + 2; cmd.rcount = 0; cmd.op = SMB_TRANS_NOCNT | SMB_TRANS_NOCMD | SMB_TRANS_7BIT; r = ioctl(fd, SMB_TRANS, &cmd); if (r == 0) { return 0; } else { printf("status r = %d slave 0x%02x\n", r, cmd.slave); return -1; } } static int mxt_write_reg(int fd, uint16_t reg, uint8_t val) { return mxt_write_reg_buf(fd, reg, &val, 1); } static int mxt_read_object(int fd, struct mxt_object *obj, void *rbuf, int rbytes) { uint16_t reg = obj->start_pos_lsb + (obj->start_pos_msb << 8); int bytes = obj->size_minus_one + 1; if (bytes > rbytes) bytes = rbytes; return mxt_read_reg(fd, reg, rbuf, bytes); } static int mxt_t6_command(int fd, uint16_t t6cmd, uint8_t t6val, int waitforme) { uint8_t status; mxt_write_reg(fd, 6 + t6cmd, t6val); while (waitforme) { if (mxt_read_reg(fd, 6 + t6cmd, &status, 1) != 1) break; if (status) return status; } return 0; } static const char * msgflagsstr(uint8_t flags) { static char buf[9]; buf[0] = (flags & MXT_MSGF_DETECT) ? 'D' : '.'; buf[1] = (flags & MXT_MSGF_PRESS) ? 'P' : '.'; buf[2] = (flags & MXT_MSGF_RELEASE) ? 'R' : '.'; buf[3] = (flags & MXT_MSGF_MOVE) ? 'M' : '.'; buf[4] = (flags & MXT_MSGF_VECTOR) ? 'V' : '.'; buf[5] = (flags & MXT_MSGF_AMP) ? 'A' : '.'; buf[6] = (flags & MXT_MSGF_SUPPRESS) ? 'S' : '.'; buf[7] = (flags & MXT_MSGF_UNGRIP) ? 'U' : '.'; return buf; } int main(int ac, char **av) { uint8_t rbuf[1024]; struct mxt_rollup rup; struct mxt_object *obj; int fd; int i; int n; int r; size_t blksize; size_t totsize; uint32_t crc; fd = open("/dev/smb1-4a", O_RDWR); printf("fd = %d\n", fd); r = mxt_t6_command(fd, 0/*RESET*/, 0x01, 1); printf("reset result %d\n", r); n = mxt_read_reg(fd, 0, &rup.info, sizeof(rup.info)); for (i = 0; i < n; ++i) printf(" %02x", ((uint8_t *)&rup.info)[i]); printf("\n"); rup.nobjs = rup.info.num_objects; blksize = sizeof(rup.info) + rup.nobjs * sizeof(struct mxt_object); totsize = blksize + sizeof(struct mxt_raw_crc); assert(totsize < sizeof(rbuf)); n = mxt_read_reg(fd, 0, rbuf, totsize); if (n != totsize) { printf("mxt_read_reg: config failed: %d/%d\n", n, totsize); exit(1); } crc = obp_convert_crc((struct mxt_raw_crc *)(rbuf + blksize)); if (obp_crc24(rbuf, blksize) != crc) { printf("info: crc failed %08x/%08x\n", crc, obp_crc24(rbuf, blksize)); exit(1); } rup.objs = (void *)(rbuf + sizeof(rup.info)); for (i = 0; i < rup.nobjs; ++i) { obj = &rup.objs[i]; printf("object %d (%s) {\n", obj->type, mxt_gettypestring(obj->type)); printf(" position = %d\n", obj->start_pos_lsb + (obj->start_pos_msb << 8)); printf(" size = %d\n", obj->size_minus_one + 1); printf(" instances= %d\n", obj->instances_minus_one + 1); printf(" numids = %d\n", obj->num_report_ids); } printf("\n"); fflush(stdout); obj = mxt_findobject(&rup, MXT_GEN_MESSAGEPROCESSOR); assert(obj != NULL); for (;;) { mxt_message_t msg; n = mxt_read_object(fd, obj, &msg, sizeof(msg)); if (msg.any.reportid == 255) continue; for (i = 0; i < n; ++i) printf(" %02x", ((uint8_t *)&msg)[i]); printf(" trk=%02x f=%s x=%-4d y=%-4d p=%d amp=%d\n", msg.any.reportid, msgflagsstr(msg.touch.flags), (msg.touch.pos[0] << 4) | ((msg.touch.pos[2] >> 4) & 0x0F), (msg.touch.pos[1] << 4) | ((msg.touch.pos[2]) & 0x0F), msg.touch.area, msg.touch.amplitude); usleep(100000); } }