X-Git-Url: http://sigaev.ru/git/gitweb.cgi?p=trinked.git;a=blobdiff_plain;f=trinket.c;h=002687cb82415fc5244f0bf4c3117c60f825cb3a;hp=fa6598d529812c5bf66145a3c97698572876aaa7;hb=3e2a1713f39de52bb9302648f473c0bd43406bd4;hpb=c8931da2925ab4fc4c9def8311228bb98ff7cb23 diff --git a/trinket.c b/trinket.c index fa6598d..002687c 100644 --- a/trinket.c +++ b/trinket.c @@ -28,6 +28,8 @@ #include #include +#include + #include #include @@ -278,3 +280,82 @@ trinketGetCumDose(double *value) { return ERR_OK; } + +TrinketErrorCode +trinketSetAlarmLevel(double value[N_ALARM_LEVELS]) { + const TrinketProtoDesc *proto = &protoDesc[CMD_ALARM_LEVELS]; + struct { + ProtoHeader header; + uint8_t begin; + uint8_t len; + uint8_t cmd; + float levels[N_ALARM_LEVELS]; + uint8_t end; + } cmd = { + {REPORT_ID, proto->cmdLen}, + BEGIN_COMMAND, + proto->cmdLen, + proto->cmdId, + {0,0,0,0,0}, + END_COMMAND + }; + struct packed_struct { + ProtoHeader header; + uint8_t begin; + uint16_t len; + float payload[N_ALARM_LEVELS]; + uint8_t end; + } resp; + int r; + + tassert(proto->cmdId == CMD_ALARM_LEVELS); + tassert(sizeof(cmd) == cmd.len + sizeof(ProtoHeader)); + tassert(sizeof(resp) == proto->respLen + sizeof(ProtoHeader)); + + memcpy(cmd.levels, value, sizeof(value[0]) * N_ALARM_LEVELS); + + r = hid_write(trinketDev, (unsigned char*)&cmd, sizeof(cmd)); + + if (r < 0 || r != sizeof(cmd)) { + tlog(TL_WARN, "hid_send_feature_report returns %d instead of %u", r, cmd.len); + return ERR_ERROR; + } + + /* must be assigned to 0x3F by the host */ + resp.header.reportId = REPORT_ID; + + r = hid_read_timeout(trinketDev, (unsigned char*)&resp, sizeof(resp), DEV_TIMEOUT); + if (r < 0) { + tlog(TL_WARN, "hid_read_timeout fails"); + return ERR_NO_ANSWER; + } + + if (r != sizeof(resp)) { + tlog(TL_WARN, "hid_read_timeout returns %d instead of %u", r, (unsigned int)sizeof(resp)); + return ERR_ERROR; + } + + if (resp.header.reportId != REPORT_ID) { + tlog(TL_WARN, "hid_read_timeout returns report id %02x instead of %02x", resp.header.reportId, REPORT_ID); + return ERR_ERROR; + } + + if (resp.header.size != proto->respLen) { + tlog(TL_WARN, "hid_read_timeout returns length %u intsead if %u", resp.header.size, proto->respLen); + return ERR_PROTO; + } + + if (resp.len != proto->respLen) { + tlog(TL_WARN, "hid_read_timeout response length %u instead of %u", resp.len, proto->respLen); + return ERR_PROTO; + } + + if (!(resp.begin == ACK_ANSWER_OK && resp.end == END_ANSWER)) { + tlog(TL_WARN, "hid_read_timeout ACK %02x and ETB %02x", resp.begin, resp.end); + return ERR_PROTO; + } + + memcpy(value, resp.payload, sizeof(value[0]) * N_ALARM_LEVELS); + + return ERR_OK; +}