Skip to content

Commit 5623931

Browse files
committed
add support for simple modes
1 parent 77b2c6e commit 5623931

File tree

4 files changed

+31
-178
lines changed

4 files changed

+31
-178
lines changed

include/cmd.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ extern PyObject *cmd_get_hardware_version(void);
8787
* (and the device->values entry will be updated) or -1 on error (when
8888
* an exception will already be raised).
8989
*/
90-
extern int cmd_get_port_value(uint8_t port_id);
90+
extern int cmd_get_port_value(uint8_t port_id, uint8_t selindex);
9191

9292
/* Sends a Hub Port Info Request command for the mode info of the
9393
* given port. Fills in the port_modes_t structure with the returned

src/cmd.c

+8-82
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,10 @@ PyObject *cmd_get_firmware_version(void)
337337
}
338338

339339

340-
int cmd_get_port_value(uint8_t port_id)
340+
int cmd_get_port_value(uint8_t port_id, uint8_t selindex)
341341
{
342342
char buf[100];
343-
sprintf(buf, "port %d ; selonce 0\r", port_id);
343+
sprintf(buf, "port %d ; selonce %d\r", port_id, selindex);
344344
make_request_uart(false, TYPE_PORT_OUTPUT, port_id, buf);
345345
return 0;
346346
}
@@ -947,86 +947,12 @@ int cmd_write_mode_data(uint8_t port_id,
947947

948948
int cmd_set_mode(uint8_t port_id, uint8_t mode, uint8_t notifications)
949949
{
950-
uint8_t *response;
951-
952-
/* Mode zero appears to be a legacy */
953-
response = make_request(false, 10, TYPE_PORT_FORMAT_SETUP_SINGLE,
954-
port_id,
955-
mode,
956-
1, 0, 0, 0, /* Delta = 1 */
957-
notifications);
958-
if (response == NULL)
959-
return -1;
960-
961-
if (response[0] != 10 ||
962-
response[2] != TYPE_PORT_FORMAT_SINGLE ||
963-
response[3] != port_id ||
964-
response[4] != mode ||
965-
response[5] != 1 ||
966-
response[6] != 0 ||
967-
response[7] != 0 ||
968-
response[8] != 0 ||
969-
response[9] != notifications)
970-
{
971-
free(response);
972-
PyErr_SetString(hub_protocol_error,
973-
"Unexpected reply to Port Format Setup");
974-
return -1;
975-
}
976-
977-
free(response);
978-
if (mode == 0)
979-
return 0;
980-
981-
/* Non-legacy modes go through an unexplained dance to change
982-
* mode. First the mode is set as for mode 0 above, then
983-
* issue a device reset, then set the mode again.
984-
*/
985-
response = make_request(false, 5, TYPE_PORT_FORMAT_SETUP_COMBINED,
986-
port_id,
987-
INFO_FORMAT_RESET);
988-
if (response == NULL)
989-
return -1;
990-
991-
/* The documentation is unclear as to what response to expect.
992-
* The code shows a TYPE_PORT_FORMAT_SINGLE for the current mode.
993-
*/
994-
if (response[0] != 10 ||
995-
response[2] != TYPE_PORT_FORMAT_SINGLE ||
996-
response[3] != port_id)
997-
{
998-
free(response);
999-
PyErr_SetString(hub_protocol_error,
1000-
"Unexpected reply to Port CombiFormat (Reset)");
1001-
return -1;
1002-
}
1003-
1004-
/* Now set the mode again */
1005-
response = make_request(false, 10, TYPE_PORT_FORMAT_SETUP_SINGLE,
1006-
port_id,
1007-
mode,
1008-
1, 0, 0, 0, /* Delta = 1 */
1009-
notifications);
1010-
if (response == NULL)
1011-
return -1;
1012-
1013-
if (response[0] != 10 ||
1014-
response[2] != TYPE_PORT_FORMAT_SINGLE ||
1015-
response[3] != port_id ||
1016-
response[4] != mode ||
1017-
response[5] != 1 ||
1018-
response[6] != 0 ||
1019-
response[7] != 0 ||
1020-
response[8] != 0 ||
1021-
response[9] != notifications)
1022-
{
1023-
free(response);
1024-
PyErr_SetString(hub_protocol_error,
1025-
"Unexpected reply to Port Format Setup");
1026-
return -1;
1027-
}
1028-
1029-
free(response);
950+
char buf[200];
951+
if(notifications)
952+
sprintf(buf, "port %u ; combi %d; select %d\r", port_id, mode, mode);
953+
else
954+
sprintf(buf, "port %u ; combi %d; selonce %d\r", port_id, mode, mode);
955+
make_request_uart(false, TYPE_PORT_OUTPUT, port_id, buf);
1030956
return 0;
1031957
}
1032958

src/device.c

+21-93
Original file line numberDiff line numberDiff line change
@@ -805,93 +805,15 @@ Device_mode(PyObject *self, PyObject *args)
805805
}
806806

807807

808-
static float rescale_float(float value,
809-
min_max_t *inrange,
810-
min_max_t *outrange)
811-
{
812-
float in_interval = inrange->max - inrange->min;
813-
float out_interval = outrange->max - outrange->min;
814-
815-
return ((value - inrange->min) *
816-
out_interval / in_interval) + outrange->min;
817-
}
818-
819-
820-
static long rescale_long(long value, min_max_t *inrange, min_max_t *outrange)
821-
{
822-
return (long)(rescale_float((float)value, inrange, outrange) + 0.5);
823-
}
824-
825-
826-
static PyObject *convert_raw(PyObject *value, int format, mode_info_t *mode)
827-
{
828-
if (PyLong_Check(value))
829-
{
830-
long long_value = PyLong_AsLong(value);
831-
832-
if (long_value == -1 && PyErr_Occurred() != NULL)
833-
return NULL;
834-
835-
switch (format)
836-
{
837-
case DEVICE_FORMAT_PERCENT:
838-
long_value = rescale_long(long_value,
839-
&mode->raw,
840-
&mode->percent);
841-
break;
842-
843-
case DEVICE_FORMAT_SI:
844-
long_value = rescale_long(long_value,
845-
&mode->raw,
846-
&mode->si);
847-
break;
848-
849-
default:
850-
break;
851-
}
852-
return PyLong_FromLong(long_value);
853-
}
854-
else if (PyFloat_Check(value))
855-
{
856-
float fvalue = (float)PyFloat_AsDouble(value);
857-
858-
if (fvalue == -1.0 && PyErr_Occurred() != NULL)
859-
return NULL;
860-
861-
switch (format)
862-
{
863-
case DEVICE_FORMAT_PERCENT:
864-
fvalue = rescale_float(fvalue,
865-
&mode->raw,
866-
&mode->percent);
867-
break;
868-
869-
case DEVICE_FORMAT_SI:
870-
fvalue = rescale_float(fvalue,
871-
&mode->raw,
872-
&mode->si);
873-
break;
874-
875-
default:
876-
break;
877-
}
878-
return PyFloat_FromDouble((double)fvalue);
879-
}
880-
else if (value == Py_None)
881-
{
882-
Py_RETURN_NONE;
883-
}
884-
885-
/* Otherwise this is unexpected */
886-
PyErr_SetString(cmd_get_exception(), "Invalid value");
887-
return NULL;
888-
}
889-
890-
891808
static int get_value(DeviceObject *device)
892809
{
893810
device->rx_error = DO_RXERR_NONE;
894-
if (cmd_get_port_value(port_get_id(device->port)) < 0)
811+
812+
uint8_t selindex = 0;
813+
if (device->current_mode != MODE_IS_COMBI)
814+
selindex = device->current_mode;
815+
816+
if (cmd_get_port_value(port_get_id(device->port), selindex) < 0)
895817
{
896818
PyObject *hub_protocol_exception = cmd_get_exception();
897819

@@ -988,30 +910,31 @@ Device_get(PyObject *self, PyObject *args)
988910
* SI (2).
989911
*/
990912

991-
if (/*device->current_mode != MODE_IS_COMBI*/ 1 == 0)
913+
if (device->current_mode != MODE_IS_COMBI)
992914
{
993915
/* Simple (single) mode */
994916
/* Get the current mode data */
995917
mode = &device->modes[device->current_mode];
996918
result_count = PyList_Size(device->values);
997-
if (result_count != mode->format.datasets)
919+
/*if (result_count != mode->format.datasets)
998920
{
999921
PyErr_SetString(cmd_get_exception(),
1000922
"Device value length mismatch");
1001923
return NULL;
1002-
}
924+
}*/
1003925

1004926
/* We wish to return a list with "mode->format->datasets" data
1005927
* values.
1006928
*/
1007-
if ((results = PyList_New(mode->format.datasets)) == NULL)
929+
930+
result_count = PyList_Size(device->values);
931+
if ((results = PyList_New(result_count)) == NULL)
1008932
return NULL;
1009933

1010934
/* device->values is a list containing result_count elements */
1011935
for (i = 0; i < result_count; i++)
1012936
{
1013937
PyObject *value = PyList_GetItem(device->values, i);
1014-
value = convert_raw(value, format, mode);
1015938
if (value == NULL)
1016939
{
1017940
Py_DECREF(results);
@@ -1086,9 +1009,9 @@ Device_callback(PyObject *self, PyObject *args)
10861009

10871010
if(device->num_combi_modes == 0)
10881011
{
1089-
/*if (set_simple_mode(device, device->current_mode) < 0){
1012+
if (set_simple_mode(device, device->current_mode) < 0){
10901013
return NULL;
1091-
}*/
1014+
}
10921015
}
10931016
else
10941017
{
@@ -1580,6 +1503,7 @@ int device_new_combi_value(PyObject *self,
15801503
mode_info_t *mode;
15811504
int bytes_consumed;
15821505
int i;
1506+
int modes;
15831507

15841508
device->is_mode_busy = 0;
15851509

@@ -1592,6 +1516,9 @@ int device_new_combi_value(PyObject *self,
15921516

15931517
mode_number = (device->combi_mode[entry] >> 4) & 0x0f;
15941518
mode = &device->modes[mode_number];
1519+
modes = device->num_combi_modes;
1520+
if (device->current_mode != MODE_IS_COMBI)
1521+
modes = entry+1;
15951522

15961523
bytes_consumed = read_value_new(buffer, &value);
15971524
if (bytes_consumed < 0)
@@ -1601,14 +1528,14 @@ int device_new_combi_value(PyObject *self,
16011528
}
16021529

16031530
/* This is not terribly efficient... */
1604-
if ((values = PyList_New(device->num_combi_modes)) == NULL)
1531+
if ((values = PyList_New(modes)) == NULL)
16051532
{
16061533
Py_DECREF(value);
16071534
device->rx_error = DO_RXERR_INTERNAL;
16081535
return -1;
16091536
}
16101537

1611-
for (i = 0; i < device->num_combi_modes; i++)
1538+
for (i = 0; i < modes; i++)
16121539
{
16131540
if (i == entry)
16141541
{
@@ -1831,5 +1758,6 @@ int device_set_device_format(PyObject *device, uint8_t modei, uint8_t type)
18311758
mode_info_t *mode;
18321759
mode = &dev->modes[modei];
18331760
mode->format.type = type;
1761+
dev->num_modes = modei;
18341762
return 0;
18351763
}

src/uart.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ void parse_line(char *serbuf)
399399
}
400400
} else if (serbuf[2] == '>') {
401401
parsed = 1;
402-
} else if (serbuf[2] == 'C') {
402+
} else if (serbuf[2] == 'C' || serbuf[2] == 'M') {
403403
//int combiindex = serbuf[3] - 48;
404404
char *tmp = malloc((strlen(serbuf) - 5) + 1);
405405
memcpy(tmp, serbuf + 5, strlen(serbuf) - 5);
@@ -419,7 +419,6 @@ void parse_line(char *serbuf)
419419
token = strtok(NULL, " ");
420420
mcount++;
421421
}
422-
423422
callback_queue(CALLBACK_DEVICE, port, CALLBACK_DATA);
424423
}
425424
}

0 commit comments

Comments
 (0)