diff --git a/hardware/cem-dt-885x/api.c b/hardware/cem-dt-885x/api.c index e19ecc4f..22e6c7a5 100644 --- a/hardware/cem-dt-885x/api.c +++ b/hardware/cem-dt-885x/api.c @@ -17,6 +17,7 @@ * along with this program. If not, see . */ +#include #include "protocol.h" #define SERIALCOMM "9600/8n1" @@ -32,8 +33,13 @@ static const int32_t hwcaps[] = { SR_CONF_LIMIT_SAMPLES, SR_CONF_CONTINUOUS, SR_CONF_DATALOG, + SR_CONF_SPL_WEIGHT_FREQ, }; +static const char *weight_freq[] = { + "A", + "C", +}; SR_PRIV struct sr_dev_driver cem_dt_885x_driver_info; static struct sr_dev_driver *di = &cem_dt_885x_driver_info; @@ -159,6 +165,7 @@ static int cleanup(void) static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi) { struct dev_context *devc; + int tmp; if (!sdi) return SR_ERR_ARG; @@ -171,6 +178,15 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi) case SR_CONF_DATALOG: *data = g_variant_new_boolean(cem_dt_885x_recording_get(sdi)); break; + case SR_CONF_SPL_WEIGHT_FREQ: + tmp = cem_dt_885x_weight_freq_get(sdi); + if (tmp == SR_MQFLAG_SPL_FREQ_WEIGHT_A) + *data = g_variant_new_string("A"); + else if (tmp == SR_MQFLAG_SPL_FREQ_WEIGHT_C) + *data = g_variant_new_string("C"); + else + return SR_ERR; + break; default: return SR_ERR_NA; } @@ -183,6 +199,7 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi) struct dev_context *devc; uint64_t tmp_u64; int ret; + const char *tmp_str; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; @@ -208,6 +225,17 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi) ret = cem_dt_885x_recording_set(sdi, FALSE); } break; + case SR_CONF_SPL_WEIGHT_FREQ: + tmp_str = g_variant_get_string(data, NULL); + if (!strcmp(tmp_str, "A")) + ret = cem_dt_885x_weight_freq_set(sdi, + SR_MQFLAG_SPL_FREQ_WEIGHT_A); + else if (!strcmp(tmp_str, "C")) + ret = cem_dt_885x_weight_freq_set(sdi, + SR_MQFLAG_SPL_FREQ_WEIGHT_C); + else + return SR_ERR_ARG; + break; default: ret = SR_ERR_NA; } @@ -231,6 +259,9 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t)); break; + case SR_CONF_SPL_WEIGHT_FREQ: + *data = g_variant_new_strv(weight_freq, ARRAY_SIZE(weight_freq)); + break; default: return SR_ERR_NA; } diff --git a/hardware/cem-dt-885x/protocol.c b/hardware/cem-dt-885x/protocol.c index 3b1d2915..c2def3e3 100644 --- a/hardware/cem-dt-885x/protocol.c +++ b/hardware/cem-dt-885x/protocol.c @@ -318,7 +318,8 @@ static int wait_for_token(const struct sr_dev_inst *sdi, char *tokens, int timeo /* cmd is the command to send, tokens are the tokens that denote the state * which the command affects. The first token is the desired state. */ -SR_PRIV int cem_dt_885x_toggle(const struct sr_dev_inst *sdi, uint8_t cmd, char *tokens) +SR_PRIV int cem_dt_885x_toggle(const struct sr_dev_inst *sdi, uint8_t cmd, + char *tokens, int timeout) { struct dev_context *devc; struct sr_serial_dev_inst *serial; @@ -332,8 +333,7 @@ SR_PRIV int cem_dt_885x_toggle(const struct sr_dev_inst *sdi, uint8_t cmd, char while (TRUE) { if (serial_write(serial, (const void *)&cmd, 1) != 1) return SR_ERR; - /* Notifications are sent at 2Hz minimum */ - if (wait_for_token(sdi, tokens, 510) == SR_ERR) + if (wait_for_token(sdi, tokens, timeout) == SR_ERR) return SR_ERR; if (devc->token == tokens[0]) /* It worked. */ @@ -391,7 +391,72 @@ SR_PRIV int cem_dt_885x_recording_set(const struct sr_dev_inst *sdi, gboolean st /* Nothing to do. */ return SR_OK; - ret = cem_dt_885x_toggle(sdi, CMD_TOGGLE_RECORDING, tokens); + /* Recording state notifications are sent at 2Hz, so allow just over + * that, 510ms, for the state to come in. */ + ret = cem_dt_885x_toggle(sdi, CMD_TOGGLE_RECORDING, tokens, 510); + + return ret; +} + +SR_PRIV int cem_dt_885x_weight_freq_get(const struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + int cur_setting; + char tokens[5]; + + devc = sdi->priv; + + cur_setting = devc->cur_mqflags & (SR_MQFLAG_SPL_FREQ_WEIGHT_A | SR_MQFLAG_SPL_FREQ_WEIGHT_C); + if (cur_setting == 0) { + /* Didn't pick up device state yet. */ + tokens[0] = TOKEN_WEIGHT_FREQ_A; + tokens[1] = TOKEN_WEIGHT_FREQ_C; + tokens[2] = -1; + if (wait_for_token(sdi, tokens, 0) != SR_OK) + return SR_ERR; + if (devc->token == TOKEN_WEIGHT_FREQ_A) + return SR_MQFLAG_SPL_FREQ_WEIGHT_A; + else + return SR_MQFLAG_SPL_FREQ_WEIGHT_C; + } else + return cur_setting; + +} + +SR_PRIV int cem_dt_885x_weight_freq_set(const struct sr_dev_inst *sdi, int freqw) +{ + struct dev_context *devc; + int cur_setting, ret; + char tokens[5]; + + devc = sdi->priv; + + cur_setting = devc->cur_mqflags & (SR_MQFLAG_SPL_FREQ_WEIGHT_A | SR_MQFLAG_SPL_FREQ_WEIGHT_C); + if (cur_setting == freqw) + /* Already set to this frequency weighting. */ + return SR_OK; + + /* The toggle below needs the desired state in first position. */ + if (freqw == SR_MQFLAG_SPL_FREQ_WEIGHT_A) { + tokens[0] = TOKEN_WEIGHT_FREQ_A; + tokens[1] = TOKEN_WEIGHT_FREQ_C; + } else { + tokens[0] = TOKEN_WEIGHT_FREQ_C; + tokens[1] = TOKEN_WEIGHT_FREQ_A; + } + tokens[2] = -1; + + if (cur_setting == 0) { + /* Didn't pick up device state yet. */ + if (wait_for_token(sdi, tokens, 0) != SR_OK) + return SR_ERR; + if (devc->token == tokens[0]) + /* Nothing to do. */ + return SR_OK; + } + + /* 10ms timeout seems to work best for this. */ + ret = cem_dt_885x_toggle(sdi, CMD_TOGGLE_WEIGHT_FREQ, tokens, 10); return ret; } diff --git a/hardware/cem-dt-885x/protocol.h b/hardware/cem-dt-885x/protocol.h index e5030f72..7bf6ea8e 100644 --- a/hardware/cem-dt-885x/protocol.h +++ b/hardware/cem-dt-885x/protocol.h @@ -68,6 +68,7 @@ enum { enum { CMD_TOGGLE_RECORDING = 0x55, + CMD_TOGGLE_WEIGHT_FREQ = 0x99, }; /** Private, per-device-instance driver context. */ @@ -104,5 +105,7 @@ enum { SR_PRIV int cem_dt_885x_receive_data(int fd, int revents, void *cb_data); SR_PRIV int cem_dt_885x_recording_set(const struct sr_dev_inst *sdi, gboolean start); SR_PRIV gboolean cem_dt_885x_recording_get(const struct sr_dev_inst *sdi); +SR_PRIV int cem_dt_885x_weight_freq_get(const struct sr_dev_inst *sdi); +SR_PRIV int cem_dt_885x_weight_freq_set(const struct sr_dev_inst *sdi, int freqw); #endif