Skip to content

Commit fe87c8a

Browse files
Fixed iso15765-2 transmit / receive.
-Fixed iso15765_receive_message(), was useless before. -Fixed cm_iso157652_tx_message_object data not being able to assign a tuple or list -Fixed cm_iso157652_*x_message_object flags variable truncating to first byte. -Added iso15765-2 example. Signed-off-by: David Rebbe <drebbe@intrepidcs.com>
1 parent e6c83b6 commit fe87c8a

5 files changed

Lines changed: 150 additions & 9 deletions

File tree

examples/iso15765_example.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import ics
2+
3+
enable_print_message = False
4+
enable_use_server = True
5+
6+
# Helper Functions ##########################################################
7+
def dev_name(device):
8+
if int("AA0000", 36) < device.SerialNumber < int("ZZZZZZ", 36):
9+
return device.Name + " " + ics.base36enc(device.SerialNumber)
10+
else:
11+
return device.Name + " " + str(device.SerialNumber)
12+
13+
def print_message(msg):
14+
if not enable_print_message:
15+
if isinstance(msg, ics.SpyMessage):
16+
print('\tArbID: {}\tData: {}'.format(hex(msg.ArbIDOrHeader), [hex(x) for x in msg.Data]))
17+
return
18+
print('\t' + str(type(msg)))
19+
for attribute in dir(msg):
20+
if attribute.startswith("_"):
21+
continue
22+
length = len(attribute)
23+
if attribute == 'data':
24+
print("\t\t{}:{}{}".format(attribute, " "*(30-length), msg.data[:msg.num_bytes]))
25+
else:
26+
value = getattr(msg, attribute)
27+
try:
28+
value = hex(value)
29+
except:
30+
pass
31+
print("\t\t{}:{}{}".format(attribute, " "*(30-length), value))
32+
print()
33+
34+
def open_device(index=0):
35+
device = None
36+
if enable_use_server:
37+
# ics.open_device() won't open a device if we have handles open already
38+
# so we need to find them and specify which ones to connect to.
39+
devices = ics.find_devices()
40+
print("Opening Device {} (Open Client handles: {})...".format(dev_name(devices[index]), devices[index].NumberOfClients))
41+
ics.open_device(devices[index])
42+
device = devices[index]
43+
else:
44+
print("Opening Device...")
45+
device = ics.open_device()
46+
print("Opened Device %s." % dev_name(device))
47+
return device
48+
49+
# Iso15765 Fuctions #########################################################
50+
def transmit_iso15765_msg(device, netid=ics.NETID_HSCAN, is_canfd=False):
51+
number_of_bytes = 64
52+
msg = ics.CmISO157652TxMessage()
53+
msg.id = 0x7E0
54+
msg.vs_netid = netid
55+
msg.num_bytes = number_of_bytes
56+
msg.padding = 0xAA
57+
# Flow Control
58+
msg.fc_id = 0x7E8
59+
msg.fc_id_mask = 0xFFF
60+
msg.flowControlExtendedAddress = 0xFE
61+
msg.fs_timeout = 0x10 # ms
62+
msg.fs_wait = 0x3000 # ms
63+
msg.blockSize = 0
64+
msg.stMin = 0
65+
# CmISO157652TxMessage.flags bitfield union isn't implemented as of 2.12, we need to do it manually.
66+
msg.flags = 0
67+
# paddingEnable
68+
msg.flags |= (1 << 6)
69+
# CANFD: Enable + BRS
70+
if is_canfd:
71+
msg.flags |= (1 << 7) | (1 << 8)
72+
# tx_dl
73+
msg.flags |= (8 << 24)
74+
# Data
75+
msg.data = [x for x in range(number_of_bytes)]
76+
77+
# Transmit the message
78+
print("Transmitting iso15765 message on {}...".format(dev_name(device)))
79+
ics.iso15765_transmit_message(device, netid, msg, 3000)
80+
# Wait for the messages to be transmitted, this can be calculated a lot better but works here.
81+
time.sleep((((number_of_bytes/8)*msg.fs_timeout)/1000.0)+0.5)
82+
#print_message(msg)
83+
print("Transmitted iso15765 message on {}.".format(dev_name(device)))
84+
85+
def setup_rx_iso15765_msg(device, netid=ics.NETID_HSCAN, is_canfd=False):
86+
msg = ics.CmISO157652RxMessage()
87+
88+
msg.id = 0x7E0
89+
msg.vs_netid = netid
90+
msg.padding = 0xAA
91+
msg.id_mask = 0xFFF
92+
msg.fc_id = 0x7E8
93+
msg.blockSize = 100
94+
msg.stMin = 10
95+
msg.cf_timeout = 1000
96+
# CmISO157652RxMessage.flags bitfield union isn't implemented as of 2.12, we need to do it manually.
97+
msg.flags = 0
98+
# paddingEnable
99+
msg.flags |= (1 << 6)
100+
# CANFD: Enable + BRS
101+
if is_canfd:
102+
msg.flags |= (1 << 7) | (1 << 8)
103+
104+
print_message(msg)
105+
print("Setting up iso15765 message on {}...".format(dev_name(device)))
106+
ics.iso15765_receive_message(device, netid, msg)
107+
print("Setup iso15765 message on {}.".format(dev_name(device)))
108+
109+
110+
def get_iso15765_msgs(device):
111+
msgs, error_count = ics.get_messages(device)
112+
print("Received {} messages with {} errors.".format(len(msgs), error_count))
113+
for i, m in enumerate(msgs):
114+
print('Message #{}\t'.format(i+1), end='')
115+
print_message(m)
116+
117+
if __name__ == "__main__":
118+
import time
119+
netid = ics.NETID_HSCAN
120+
121+
tx_device = open_device(0)
122+
rx_device = open_device(1)
123+
124+
ics.iso15765_enable_networks(tx_device, netid)
125+
ics.iso15765_enable_networks(rx_device, netid)
126+
setup_rx_iso15765_msg(rx_device)
127+
transmit_iso15765_msg(tx_device)
128+
get_iso15765_msgs(rx_device)
129+
130+
ics.iso15765_disable_networks(tx_device)
131+
ics.iso15765_disable_networks(rx_device)

include/methods.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,13 +1007,15 @@ PyObject* meth_enable_network_com(PyObject* self, PyObject* args);
10071007

10081008
// (void* hObject, unsigned int iIndex, const stCM_ISO157652_RxMessage * pRxMessage)
10091009
#define _DOC_ISO15765_RECEIVE_MESSAGE \
1010-
MODULE_NAME".iso15765_receive_message(device, iIndex)\n" \
1010+
MODULE_NAME".iso15765_receive_message(device, netid, rx_msg)\n" \
10111011
"\n" \
1012-
"Receives an ISO15765 Message.\n" \
1012+
"Setup rx ISO15765 Message.\n" \
10131013
"\n" \
10141014
"Args:\n" \
10151015
"\tdevice (:class:`"MODULE_NAME"."NEO_DEVICE_OBJECT_NAME"`): :class:`"MODULE_NAME"."NEO_DEVICE_OBJECT_NAME"`\n\n" \
10161016
"\n" \
1017+
"\tprx_msg (:class:`"MODULE_NAME"."CM_ISO157652_RX_MESSAGE_OBJECT_NAME"`): :class:`"MODULE_NAME"."CM_ISO157652_RX_MESSAGE_OBJECT_NAME"`\n\n" \
1018+
"\n" \
10171019
"Raises:\n" \
10181020
"\t:class:`"MODULE_NAME".RuntimeError`\n" \
10191021
"\n" \

include/object_cm_iso157652_rx_message.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static PyMemberDef cm_iso157652_rx_message_object_members[] = {
4848
{ "stMin", T_UBYTE, offsetof(cm_iso157652_rx_message_object, s.stMin), 0, "Minimum seperation time (between consecutive frames) to report in flow control response"},
4949
{ "cf_timeout", T_USHORT, offsetof(cm_iso157652_rx_message_object, s.cf_timeout), 0, "max timeout (ms) for waiting on consecutive frame. Set this to N_CR_MAX's value in J2534"},
5050
// TODO: Support bit fields here
51-
{ "flags", T_UBYTE, offsetof(cm_iso157652_rx_message_object, s.flags), 0, ""},
51+
{ "flags", T_UINT, offsetof(cm_iso157652_rx_message_object, s.flags), 0, ""},
5252
{ "reserved", T_OBJECT_EX, offsetof(cm_iso157652_rx_message_object, s.reserved), 0, ""},
5353
{ NULL, 0, 0, 0, 0 },
5454
};

include/object_cm_iso157652_tx_message.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ static PyMemberDef cm_iso157652_tx_message_object_members[] = {
5252
{ "data", T_OBJECT_EX, offsetof(cm_iso157652_tx_message_object, s.data), 0, "The data"},
5353
{ "num_bytes", T_UINT, offsetof(cm_iso157652_tx_message_object, s.num_bytes), 0, "Number of data bytes"},
5454
// TODO: Support bit fields here
55-
{ "flags", T_UBYTE, offsetof(cm_iso157652_tx_message_object, s.flags), 0, ""},
55+
{ "flags", T_UINT, offsetof(cm_iso157652_tx_message_object, s.flags), 0, ""},
5656
{ NULL, 0, 0, 0, 0 },
5757
};
5858

@@ -97,7 +97,7 @@ static int cm_iso157652_tx_message_object_setattr(PyObject *o, PyObject *name, P
9797
cm_iso157652_tx_message_object* obj = (cm_iso157652_tx_message_object*)o;
9898
if (PyUnicode_CompareWithASCIIString(name, "data") == 0) {
9999
// Make sure we are a tuple and len() == 8
100-
if (!PyTuple_Check(value) || !PyList_Check(value)) {
100+
if (!PyTuple_Check(value) && !PyList_Check(value)) {
101101
PyErr_Format(PyExc_AttributeError,
102102
"'%.50s' object attribute '%.400s' needs to be a tuple or list",
103103
MODULE_NAME "." CM_ISO157652_TX_MESSAGE_OBJECT_NAME, name);

src/methods.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,37 +3673,45 @@ PyObject* obj = NULL;
36733673
PyObject* meth_iso15765_receive_message(PyObject* self, PyObject* args)
36743674
{
36753675
PyObject* obj = NULL;
3676+
PyObject* obj_rx_msg = NULL;
36763677
unsigned int iIndex = 0;
3677-
PyObject* obj_rx_msg = PyObject_CallObject((PyObject*)&cm_iso157652_rx_message_object_type, NULL);
3678-
if (!PyArg_ParseTuple(args, arg_parse("Oi:", __FUNCTION__), &obj, &iIndex)) {
3678+
//PyObject* obj_rx_msg = PyObject_CallObject((PyObject*)&cm_iso157652_rx_message_object_type, NULL);
3679+
if (!PyArg_ParseTuple(args, arg_parse("OiO:", __FUNCTION__), &obj, &iIndex, &obj_rx_msg)) {
36793680
return NULL;
36803681
}
36813682
if (!PyNeoDevice_CheckExact(obj)) {
36823683
return set_ics_exception(exception_runtime_error(), "Argument must be of type " MODULE_NAME "." NEO_DEVICE_OBJECT_NAME);
36833684
}
3684-
if (!PyCmISO157652TxMessage_Check(obj_rx_msg)) {
3685+
if (!PyCmISO157652RxMessage_Check(obj_rx_msg)) {
36853686
return set_ics_exception(exception_runtime_error(), "Argument must be of type " MODULE_NAME "." CM_ISO157652_RX_MESSAGE_OBJECT_NAME);
36863687
}
3688+
Py_XINCREF(obj_rx_msg);
36873689
cm_iso157652_rx_message_object *temp = (cm_iso157652_rx_message_object*)obj_rx_msg;
36883690
ICS_HANDLE handle = PyNeoDevice_GetHandle(obj);
36893691
try
36903692
{
36913693
ice::Library* lib = dll_get_library();
36923694
if (!lib) {
36933695
char buffer[512];
3696+
Py_DECREF(obj_rx_msg);
36943697
return set_ics_exception(exception_runtime_error(), dll_get_error(buffer));
36953698
}
3699+
//stCM_ISO157652_RxMessage rx_msg_temp = {0};
3700+
//memcpy(&rx_msg_temp, &(temp->s), sizeof(temp->s));
36963701
ice::Function<int __stdcall (ICS_HANDLE, unsigned int, stCM_ISO157652_RxMessage*)> icsneoISO15765_ReceiveMessage(lib, "icsneoISO15765_ReceiveMessage");
36973702
Py_BEGIN_ALLOW_THREADS
36983703
if (!icsneoISO15765_ReceiveMessage(handle, iIndex, &temp->s)) {
36993704
Py_BLOCK_THREADS
3705+
Py_DECREF(obj_rx_msg);
37003706
return set_ics_exception(exception_runtime_error(), "icsneoISO15765_ReceiveMessage() Failed");
37013707
}
37023708
Py_END_ALLOW_THREADS
3703-
return obj_rx_msg;
3709+
Py_DECREF(obj_rx_msg);
3710+
Py_RETURN_NONE;
37043711
}
37053712
catch (ice::Exception& ex)
37063713
{
3714+
Py_DECREF(obj_rx_msg);
37073715
return set_ics_exception(exception_runtime_error(), (char*)ex.what());
37083716
}
37093717
return set_ics_exception(exception_runtime_error(), "This is a bug!");

0 commit comments

Comments
 (0)