add trinketSetAlarmLevel master
authorTeodor Sigaev <teodor@sigaev.ru>
Wed, 25 May 2016 21:55:21 +0000 (00:55 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Wed, 25 May 2016 21:55:21 +0000 (00:55 +0300)
trinket.c
trinket.h

index fa6598d..002687c 100644 (file)
--- a/trinket.c
+++ b/trinket.c
@@ -28,6 +28,8 @@
 
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
+
 #include <hidapi/hidapi.h>
 
 #include <tlog.h>
@@ -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;
+}
index 2f7fba9..5c38f16 100644 (file)
--- a/trinket.h
+++ b/trinket.h
@@ -39,5 +39,6 @@ TrinketErrorCode      trinketOpen();
 void                           trinketClose();
 TrinketErrorCode       trinketPing();
 TrinketErrorCode       trinketGetCumDose(double *value);
-
+#define N_ALARM_LEVELS  (5)
+TrinketErrorCode       trinketSetAlarmLevel(double value[N_ALARM_LEVELS]);
 #endif