Skip to content

Commit bb6a887

Browse files
Squashed commit of the following:
commit 47828b9 Author: juergen <[email protected]> Date: Thu May 19 07:59:02 2022 +0200 some prints removed commit 494dbc0 Author: juergen <[email protected]> Date: Tue May 3 07:37:56 2022 +0200 preparation to send j1939-22 PGs with Frame-Format FBFF (standard identifiers)
1 parent a60571b commit bb6a887

File tree

6 files changed

+89
-41
lines changed

6 files changed

+89
-41
lines changed

examples/j1939_22_multi_pg.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import time
33
import j1939
4+
from j1939.message_id import FrameFormat
45

56

67
logging.getLogger('j1939').setLevel(logging.DEBUG)
@@ -24,7 +25,7 @@ def on_message(priority, pgn, sa, timestamp, data):
2425
print("PGN {} length {}".format(pgn, len(data)), timestamp)
2526

2627

27-
def ca_timer_callback1(ca):
28+
def ca_timer_callback1(ca : j1939.ControllerApplication):
2829
"""Callback for sending messages
2930
3031
This callback is registered at the ECU timer event mechanism to be
@@ -43,10 +44,13 @@ def ca_timer_callback1(ca):
4344

4445
# sending broadcast message
4546
# the following two PGNs are packed into one multi-pg, due to time-limit of 10ms and same destination address (global)
46-
ca.send_pgn(0, 0xFD, 0xED, 6, data, time_limit=0.01)
47-
ca.send_pgn(0, 0xFE, 0x32, 6, data, time_limit=0.01)
47+
ca.send_pgn(0, 0xFD, 0xED, 6, data, time_limit=0.01, frame_format=FrameFormat.FBFF) # Frame-Format FBFF
48+
ca.send_pgn(0, 0xFE, 0x32, 6, data, time_limit=0.01, frame_format=FrameFormat.FBFF) # Frame-Format FBFF
4849

49-
# sending normal peer-to-peer message, destintion address is 0x04
50+
ca.send_pgn(0, 0xFA, 0xED, 6, data, time_limit=0.01) # Frame-Format FEFF
51+
ca.send_pgn(0, 0xFB, 0x32, 6, data, time_limit=0.01) # Frame-Format FEFF
52+
53+
# sending peer-to-peer message, destintion address is 0x04
5054
# the following PGNs are transferred separately, because time limit == 0
5155
ca.send_pgn(0, 0xE0, 0x04, 6, data)
5256
ca.send_pgn(0, 0xD0, 0x04, 6, data)
@@ -62,7 +66,7 @@ def main():
6266
ecu = j1939.ElectronicControlUnit(data_link_layer='j1939-22', max_cmdt_packets=200)
6367

6468
# can fd Baud: 500k/2M
65-
ecu.connect(bustype='pcan', channel='PCAN_USBBUS1', fd=True,
69+
ecu.connect(bustype='pcan', channel='PCAN_USBBUS3', fd=True,
6670
f_clock_mhz=80, nom_brp=10, nom_tseg1=12, nom_tseg2=3, nom_sjw=1, data_brp=4, data_tseg1=7, data_tseg2=2, data_sjw=1)
6771

6872
# subscribe to all (global) messages on the bus

j1939/controller_application.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import j1939
3+
from .message_id import FrameFormat
34

45
logger = logging.getLogger(__name__)
56

@@ -246,9 +247,9 @@ def send_message(self, priority, parameter_group_number, data):
246247
raise RuntimeError("Could not send message unless address claiming has finished")
247248

248249
mid = j1939.MessageId(priority=priority, parameter_group_number=parameter_group_number, source_address=self._device_address)
249-
self._ecu.send_message(mid.can_id, data)
250+
self._ecu.send_message(mid.can_id, True, data)
250251

251-
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_limit=0):
252+
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_limit=0, frame_format=FrameFormat.FEFF):
252253
"""send a pgn
253254
:param int data_page: data page
254255
:param int pdu_format: pdu format
@@ -262,7 +263,7 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, data, time_lim
262263
if self.state != ControllerApplication.State.NORMAL:
263264
raise RuntimeError("Could not send message unless address claiming has finished")
264265

265-
return self._ecu.send_pgn(data_page, pdu_format, pdu_specific, priority, self._device_address, data, time_limit)
266+
return self._ecu.send_pgn(data_page, pdu_format, pdu_specific, priority, self._device_address, data, time_limit, frame_format)
266267

267268
def send_request(self, data_page, pgn, destination):
268269
"""send a request message
@@ -287,7 +288,7 @@ def _send_address_claimed(self, address):
287288
pgn = j1939.ParameterGroupNumber(0, 238, j1939.ParameterGroupNumber.Address.GLOBAL)
288289
mid = j1939.MessageId(priority=6, parameter_group_number=pgn.value, source_address=address)
289290
data = self._name.bytes
290-
self._ecu.send_message(mid.can_id, data)
291+
self._ecu.send_message(mid.can_id, True, data)
291292

292293
def on_request(self, src_address, dest_address, pgn):
293294
"""Callback for PGN requests

j1939/electronic_control_unit.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .parameter_group_number import ParameterGroupNumber
99
from .j1939_21 import J1939_21
1010
from .j1939_22 import J1939_22
11-
11+
from .message_id import FrameFormat
1212

1313
logger = logging.getLogger(__name__)
1414

@@ -195,7 +195,7 @@ def remove_ca(self, device_address):
195195
"""
196196
return self.j1939_dll.remove_ca(device_address)
197197

198-
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit=0):
198+
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit=0, frame_format=FrameFormat.FEFF):
199199
"""send a pgn
200200
:param int data_page: data page
201201
:param int pdu_format: pdu format
@@ -207,9 +207,9 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d
207207
after this time, the multi-pg will be sent. several pgs can thus be combined in one multi-pg.
208208
0 or no time-limit means immediate sending.
209209
"""
210-
return self.j1939_dll.send_pgn(data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit)
210+
return self.j1939_dll.send_pgn(data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format)
211211

212-
def send_message(self, can_id, data, fd_format=False):
212+
def send_message(self, can_id, extended_id, data, fd_format=False):
213213
"""Send a raw CAN message to the bus.
214214
215215
This method may be overridden in a subclass if you need to integrate
@@ -229,7 +229,7 @@ def send_message(self, can_id, data, fd_format=False):
229229

230230
if not self._bus:
231231
raise RuntimeError("Not connected to CAN bus")
232-
msg = can.Message(is_extended_id=True,
232+
msg = can.Message(is_extended_id=extended_id,
233233
arbitration_id=can_id,
234234
data=data,
235235
is_fd=fd_format,

j1939/j1939_21.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d
9292
if len(data) <= 8:
9393
# send normal message
9494
mid = MessageId(priority=priority, parameter_group_number=pgn.value, source_address=src_address)
95-
self.__send_message(mid.can_id, data)
95+
self.__send_message(mid.can_id, True, data)
9696
else:
9797
# if the PF is between 0 and 239, the message is destination dependent when pdu_specific != 255
9898
# if the PF is between 240 and 255, the message can only be broadcast
@@ -413,42 +413,42 @@ def _process_tp_dt(self, mid, dest_address, data, timestamp):
413413
def __send_tp_dt(self, src_address, dest_address, data):
414414
pgn = ParameterGroupNumber(0, 235, dest_address)
415415
mid = MessageId(priority=7, parameter_group_number=pgn.value, source_address=src_address)
416-
self.__send_message(mid.can_id, data)
416+
self.__send_message(mid.can_id, True, data)
417417

418418
def __send_tp_abort(self, src_address, dest_address, reason, pgn_value):
419419
pgn = ParameterGroupNumber(0, 236, dest_address)
420420
mid = MessageId(priority=7, parameter_group_number=pgn.value, source_address=src_address)
421421
data = [self.ConnectionMode.ABORT, reason, 0xFF, 0xFF, 0xFF, pgn_value & 0xFF, (pgn_value >> 8) & 0xFF, (pgn_value >> 16) & 0xFF]
422-
self.__send_message(mid.can_id, data)
422+
self.__send_message(mid.can_id, True, data)
423423

424424
def __send_tp_cts(self, src_address, dest_address, num_packets, next_packet, pgn_value):
425425
pgn = ParameterGroupNumber(0, 236, dest_address)
426426
mid = MessageId(priority=7, parameter_group_number=pgn.value, source_address=src_address)
427427
data = [self.ConnectionMode.CTS, num_packets, next_packet, 0xFF, 0xFF, pgn_value & 0xFF, (pgn_value >> 8) & 0xFF, (pgn_value >> 16) & 0xFF]
428-
self.__send_message(mid.can_id, data)
428+
self.__send_message(mid.can_id, True, data)
429429

430430
def __send_tp_eom_ack(self, src_address, dest_address, message_size, num_packets, pgn_value):
431431
pgn = ParameterGroupNumber(0, 236, dest_address)
432432
mid = MessageId(priority=7, parameter_group_number=pgn.value, source_address=src_address)
433433
data = [self.ConnectionMode.EOM_ACK, message_size & 0xFF, (message_size >> 8) & 0xFF, num_packets, 0xFF, pgn_value & 0xFF, (pgn_value >> 8) & 0xFF, (pgn_value >> 16) & 0xFF]
434-
self.__send_message(mid.can_id, data)
434+
self.__send_message(mid.can_id, True, data)
435435

436436
def __send_tp_rts(self, src_address, dest_address, priority, pgn_value, message_size, num_packets, max_cmdt_packets):
437437
pgn = ParameterGroupNumber(0, 236, dest_address)
438438
mid = MessageId(priority=priority, parameter_group_number=pgn.value, source_address=src_address)
439439
data = [self.ConnectionMode.RTS, message_size & 0xFF, (message_size >> 8) & 0xFF, num_packets, max_cmdt_packets, pgn_value & 0xFF, (pgn_value >> 8) & 0xFF, (pgn_value >> 16) & 0xFF]
440-
self.__send_message(mid.can_id, data)
440+
self.__send_message(mid.can_id, True, data)
441441

442442
def __send_acknowledgement(self, control_byte, group_function_value, address_acknowledged, pgn):
443443
data = [control_byte, group_function_value, 0xFF, 0xFF, address_acknowledged, (pgn & 0xFF), ((pgn >> 8) & 0xFF), ((pgn >> 16) & 0xFF)]
444444
mid = MessageId(priority=6, parameter_group_number=0x00E800, source_address=255)
445-
self.__send_message(mid.can_id, data)
445+
self.__send_message(mid.can_id, True, data)
446446

447447
def __send_tp_bam(self, src_address, priority, pgn_value, message_size, num_packets):
448448
pgn = ParameterGroupNumber(0, 236, ParameterGroupNumber.Address.GLOBAL)
449449
mid = MessageId(priority=priority, parameter_group_number=pgn.value, source_address=src_address)
450450
data = [self.ConnectionMode.BAM, message_size & 0xFF, (message_size >> 8) & 0xFF, num_packets, 0xFF, pgn_value & 0xFF, (pgn_value >> 8) & 0xFF, (pgn_value >> 16) & 0xFF]
451-
self.__send_message(mid.can_id, data)
451+
self.__send_message(mid.can_id, True, data)
452452

453453
def notify(self, can_id, data, timestamp):
454454
"""Feed incoming CAN message into this ecu.

j1939/j1939_22.py

+61-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from tkinter import E
12
from .parameter_group_number import ParameterGroupNumber
2-
from .message_id import MessageId
3+
from .message_id import MessageId, FrameFormat
34
import logging
45
import time
56
import numpy as np
@@ -87,6 +88,8 @@ def __init__(self, send_message, job_thread_wakeup, notify_subscribers, max_cmdt
8788
# specified time range in j1939-22: 10-200ms
8889
if minimum_tp_bam_dt_interval == None:
8990
self._minimum_tp_bam_dt_interval = 0.010
91+
else:
92+
self._minimum_tp_bam_dt_interval = minimum_tp_bam_dt_interval
9093

9194
# Up to 4 concurrent BAM sessions per originator address are allowed
9295
self.__bam_session_list = [True] * 4
@@ -113,8 +116,27 @@ def remove_ca(self, device_address):
113116
return False
114117

115118
def _buffer_hash(self, session_num, src_address, dest_address):
116-
"""Calcluates a hash value for the given address pair
119+
"""Calculates a hash value for the given address pair
120+
121+
:param src_address:
122+
The Source-Address the connection should bound to.
123+
:param dest_address:
124+
The Destination-Address the connection should bound to.
125+
126+
:return:
127+
The calculated hash value.
128+
129+
:rtype: int
130+
"""
131+
return ((session_num & 0xF) << 16) | ((src_address & 0xFF) << 8) | (dest_address & 0xFF)
117132

133+
def _buffer_hash_mpg(self, frame_format, msg_counter, src_address, dest_address):
134+
"""Calculates a hash value for the given multi-pg arguments
135+
136+
:param frame_format:
137+
The frame-format (FBFF, FEFF) the connection should bound to.
138+
:param msg_counter:
139+
The message counter the connection should bound to.
118140
:param src_address:
119141
The Source-Address the connection should bound to.
120142
:param dest_address:
@@ -125,10 +147,10 @@ def _buffer_hash(self, session_num, src_address, dest_address):
125147
126148
:rtype: int
127149
"""
128-
return (((session_num & 0xF) << 16) | (src_address & 0xFF) << 8) | (dest_address & 0xFF)
150+
return ((frame_format & 0xFF) << 24) | ((msg_counter & 0xFF) << 16) | ((src_address & 0xFF) << 8) | (dest_address & 0xFF)
129151

130152
def _buffer_unhash(self, hash):
131-
"""Calcluates session-number, source-address and destination-address for the given hash value
153+
"""Calculates session-number, source-address and destination-address for the given hash value
132154
133155
:param hash:
134156
The hash to be unhased
@@ -138,6 +160,17 @@ def _buffer_unhash(self, hash):
138160
"""
139161
return ((hash >> 16) & 0xFF), ((hash >> 8) & 0xFF), (hash & 0xFF)
140162

163+
def _buffer_unhash_mpg(self, hash):
164+
"""Calculates frame_format, msg_counter, source-address and destination-address for the given hash value
165+
166+
:param hash:
167+
The hash to be unhased
168+
169+
:return:
170+
The session-number, source-address and destination-address
171+
"""
172+
return ((hash >> 24) & 0xFF), ((hash >> 16) & 0xFF), ((hash >> 8) & 0xFF), (hash & 0xFF)
173+
141174
def __get_bam_session(self):
142175
for idx, i in enumerate(self.__bam_session_list):
143176
if i == True:
@@ -158,7 +191,7 @@ def __get_rts_cts_session(self):
158191
def __put_rts_cts_session(self, session):
159192
self.__rts_cts_session_list[session] = True
160193

161-
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit=0, tos = 2, trailer_format = 0):
194+
def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, data, time_limit, frame_format, tos=2, trailer_format=0):
162195
pgn = ParameterGroupNumber(data_page, pdu_format, pdu_specific)
163196
data_length = len(data)
164197

@@ -173,17 +206,24 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d
173206
cpgn = pgn.value
174207
dst_address = ParameterGroupNumber.Address.GLOBAL
175208

209+
if (frame_format==FrameFormat.FBFF):
210+
priority = 0
211+
if (dst_address!=ParameterGroupNumber.Address.GLOBAL):
212+
logger.info('FBFF message must be a broadcast type')
213+
return False
214+
176215
# create header dict
177216
cpg = {'priority': (priority & 0x7), 'tos': (tos & 0x7), 'tf': (trailer_format & 0x7), 'cpgn': (cpgn & 0x3FFFF), 'data_length': data_length, 'data': data.copy()}
178217

179218
# send immediately
180219
if time_limit == 0:
181-
self.__send_multi_pg([cpg], src_address, dst_address)
220+
self.__send_multi_pg(frame_format, [cpg], src_address, dst_address)
182221
else:
183222
session = 0
184223
deadline = time.time() + time_limit
185224
while True:
186-
hash = self._buffer_hash(session, src_address, dst_address)
225+
hash = self._buffer_hash_mpg(frame_format, session, src_address, dst_address)
226+
#hash = self._buffer_hash(session, src_address, dst_address)
187227
if hash not in self._multi_pg_snd_buffer:
188228
self._multi_pg_snd_buffer[hash] = {'deadline': deadline, 'cpg': [cpg], 'fill_level': 4 + data_length}
189229
break
@@ -209,13 +249,13 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d
209249
dest_address = ParameterGroupNumber.Address.GLOBAL
210250
session_num = self.__get_bam_session()
211251
if session_num == None:
212-
print('bam session not available')
252+
#print('bam session not available')
213253
return False
214254
else:
215255
dest_address = pdu_specific
216256
session_num = self.__get_rts_cts_session()
217257
if session_num == None:
218-
print('rts/cts session not available')
258+
#print('rts/cts session not available')
219259
return False
220260

221261
# init sequence
@@ -280,7 +320,7 @@ def send_pgn(self, data_page, pdu_format, pdu_specific, priority, src_address, d
280320

281321
return True
282322

283-
def __send_multi_pg(self, cpg_list, src_address, dst_address):
323+
def __send_multi_pg(self, frame_format, cpg_list, src_address, dst_address):
284324
# deadline reached
285325
priority = 7
286326
data = []
@@ -306,10 +346,13 @@ def __send_multi_pg(self, cpg_list, src_address, dst_address):
306346
else:
307347
data.append(0xAA)
308348

309-
mid = MessageId(priority=priority,
310-
parameter_group_number=ParameterGroupNumber.PGN.FEFF_MULTI_PG | (dst_address & 0xFF),
311-
source_address=src_address)
312-
self.__send_message(mid.can_id, data, fd_format=True)
349+
if frame_format == FrameFormat.FBFF:
350+
self.__send_message(src_address, False, data, fd_format=True)
351+
else:
352+
mid = MessageId(priority=priority,
353+
parameter_group_number=ParameterGroupNumber.PGN.FEFF_MULTI_PG | (dst_address & 0xFF),
354+
source_address=src_address)
355+
self.__send_message(mid.can_id, True, data, fd_format=True)
313356

314357

315358
def async_job_thread(self, now):
@@ -345,9 +388,9 @@ def async_job_thread(self, now):
345388
next_wakeup = buf['deadline']
346389
else:
347390
# deadline reached
348-
session_num, src_address, dst_address = self._buffer_unhash(bufid)
391+
frame_format, session_num, src_address, dst_address = self._buffer_unhash_mpg(bufid)
349392

350-
self.__send_multi_pg(buf['cpg'], src_address, dst_address)
393+
self.__send_multi_pg(frame_format, buf['cpg'], src_address, dst_address)
351394

352395
del self._multi_pg_snd_buffer[bufid]
353396

@@ -717,7 +760,7 @@ def __send_tp_cm(self, src_address, dest_address,
717760
data[10] = ( (pgn >> 8) & 0xFF )
718761
data[11] = ( (pgn >> 16) & 0xFF )
719762
# 13 up to 64 Assurance Data of full message calculated using AD Type. Total length = Size in byte 8.
720-
self.__send_message(mid.can_id, data, fd_format=True)
763+
self.__send_message(mid.can_id, True, data, fd_format=True)
721764

722765
def __send_tp_dt(self, src_address, dest_address, session_num, segment_num, data, Dtfi=0):
723766
pgn = ParameterGroupNumber(0, (ParameterGroupNumber.PGN.FD_TP_DT>>8) & 0xFF, dest_address)
@@ -739,7 +782,7 @@ def __send_tp_dt(self, src_address, dest_address, session_num, segment_num, data
739782
while len(data)<next_valid_fd_length:
740783
data.append(255)
741784

742-
self.__send_message(mid.can_id, data, fd_format=True)
785+
self.__send_message(mid.can_id, True, data, fd_format=True)
743786

744787

745788
def notify(self, can_id, data, timestamp):

j1939/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.0.8"
1+
__version__ = "2.0.9"

0 commit comments

Comments
 (0)