You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					112 lines
				
				3.3 KiB
			
		
		
			
		
	
	
					112 lines
				
				3.3 KiB
			| 
								 
											7 years ago
										 
									 | 
							
								# distutils: language = c++
							 | 
						||
| 
								 | 
							
								from libc.stdint cimport uint32_t, uint64_t
							 | 
						||
| 
								 | 
							
								from libcpp.vector cimport vector
							 | 
						||
| 
								 | 
							
								from libcpp.map cimport map
							 | 
						||
| 
								 | 
							
								from libcpp.string cimport string
							 | 
						||
| 
								 | 
							
								from libcpp cimport bool
							 | 
						||
| 
								 | 
							
								from posix.dlfcn cimport dlopen, dlsym, RTLD_LAZY
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								import subprocess
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef struct SignalPackValue:
							 | 
						||
| 
								 | 
							
								  const char* name
							 | 
						||
| 
								 | 
							
								  double value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ctypedef enum SignalType:
							 | 
						||
| 
								 | 
							
								  DEFAULT,
							 | 
						||
| 
								 | 
							
								  HONDA_CHECKSUM,
							 | 
						||
| 
								 | 
							
								  HONDA_COUNTER,
							 | 
						||
| 
								 | 
							
								  TOYOTA_CHECKSUM,
							 | 
						||
| 
								 | 
							
								  PEDAL_CHECKSUM,
							 | 
						||
| 
								 | 
							
								  PEDAL_COUNTER
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef struct Signal:
							 | 
						||
| 
								 | 
							
								  const char* name
							 | 
						||
| 
								 | 
							
								  int b1, b2, bo
							 | 
						||
| 
								 | 
							
								  bool is_signed
							 | 
						||
| 
								 | 
							
								  double factor, offset
							 | 
						||
| 
								 | 
							
								  SignalType type
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef struct Msg:
							 | 
						||
| 
								 | 
							
								  const char* name
							 | 
						||
| 
								 | 
							
								  uint32_t address
							 | 
						||
| 
								 | 
							
								  unsigned int size
							 | 
						||
| 
								 | 
							
								  size_t num_sigs
							 | 
						||
| 
								 | 
							
								  const Signal *sigs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef struct Val:
							 | 
						||
| 
								 | 
							
								  const char* name
							 | 
						||
| 
								 | 
							
								  uint32_t address
							 | 
						||
| 
								 | 
							
								  const char* def_val
							 | 
						||
| 
								 | 
							
								  const Signal *sigs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef struct DBC:
							 | 
						||
| 
								 | 
							
								  const char* name
							 | 
						||
| 
								 | 
							
								  size_t num_msgs
							 | 
						||
| 
								 | 
							
								  const Msg *msgs
							 | 
						||
| 
								 | 
							
								  const Val *vals
							 | 
						||
| 
								 | 
							
								  size_t num_vals
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ctypedef void * (*canpack_init_func)(const char* dbc_name)
							 | 
						||
| 
								 | 
							
								ctypedef uint64_t (*canpack_pack_vector_func)(void* inst, uint32_t address, const vector[SignalPackValue] &signals, int counter)
							 | 
						||
| 
								 | 
							
								ctypedef const DBC * (*dbc_lookup_func)(const char* dbc_name)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cdef class CANPacker(object):
							 | 
						||
| 
								 | 
							
								  cdef void *packer
							 | 
						||
| 
								 | 
							
								  cdef const DBC *dbc
							 | 
						||
| 
								 | 
							
								  cdef map[string, (int, int)] name_to_address_and_size
							 | 
						||
| 
								 | 
							
								  cdef map[int, int] address_to_size
							 | 
						||
| 
								 | 
							
								  cdef canpack_init_func canpack_init
							 | 
						||
| 
								 | 
							
								  cdef canpack_pack_vector_func canpack_pack_vector
							 | 
						||
| 
								 | 
							
								  cdef dbc_lookup_func dbc_lookup
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  def __init__(self, dbc_name):
							 | 
						||
| 
								 | 
							
								    can_dir = os.path.dirname(os.path.abspath(__file__))
							 | 
						||
| 
								 | 
							
								    libdbc_fn = os.path.join(can_dir, "libdbc.so")
							 | 
						||
| 
								 | 
							
								    subprocess.check_call(["make"], cwd=can_dir)
							 | 
						||
| 
								 | 
							
								    cdef void *libdbc = dlopen(libdbc_fn, RTLD_LAZY)
							 | 
						||
| 
								 | 
							
								    self.canpack_init = <canpack_init_func>dlsym(libdbc, 'canpack_init')
							 | 
						||
| 
								 | 
							
								    self.canpack_pack_vector = <canpack_pack_vector_func>dlsym(libdbc, 'canpack_pack_vector')
							 | 
						||
| 
								 | 
							
								    self.dbc_lookup = <dbc_lookup_func>dlsym(libdbc, 'dbc_lookup')
							 | 
						||
| 
								 | 
							
								    self.packer = self.canpack_init(dbc_name)
							 | 
						||
| 
								 | 
							
								    self.dbc = self.dbc_lookup(dbc_name)
							 | 
						||
| 
								 | 
							
								    num_msgs = self.dbc[0].num_msgs
							 | 
						||
| 
								 | 
							
								    for i in range(num_msgs):
							 | 
						||
| 
								 | 
							
								      msg = self.dbc[0].msgs[i]
							 | 
						||
| 
								 | 
							
								      self.name_to_address_and_size[string(msg.name)] = (msg.address, msg.size)
							 | 
						||
| 
								 | 
							
								      self.address_to_size[msg.address] = msg.size
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cdef uint64_t pack(self, addr, values, counter):
							 | 
						||
| 
								 | 
							
								    cdef vector[SignalPackValue] values_thing
							 | 
						||
| 
								 | 
							
								    cdef SignalPackValue spv
							 | 
						||
| 
								 | 
							
								    for name, value in values.iteritems():
							 | 
						||
| 
								 | 
							
								      spv.name = name
							 | 
						||
| 
								 | 
							
								      spv.value = value
							 | 
						||
| 
								 | 
							
								      values_thing.push_back(spv)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return self.canpack_pack_vector(self.packer, addr, values_thing, counter)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cdef inline uint64_t ReverseBytes(self, uint64_t x):
							 | 
						||
| 
								 | 
							
								    return (((x & 0xff00000000000000ull) >> 56) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x00ff000000000000ull) >> 40) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x0000ff0000000000ull) >> 24) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x000000ff00000000ull) >> 8) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x00000000ff000000ull) << 8) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x0000000000ff0000ull) << 24) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x000000000000ff00ull) << 40) |
							 | 
						||
| 
								 | 
							
								           ((x & 0x00000000000000ffull) << 56))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cpdef make_can_msg(self, name_or_addr, bus, values, counter=-1):
							 | 
						||
| 
								 | 
							
								    cdef int addr, size
							 | 
						||
| 
								 | 
							
								    if type(name_or_addr) == int:
							 | 
						||
| 
								 | 
							
								      addr = name_or_addr
							 | 
						||
| 
								 | 
							
								      size = self.address_to_size[name_or_addr]
							 | 
						||
| 
								 | 
							
								    else:
							 | 
						||
| 
								 | 
							
								      addr, size = self.name_to_address_and_size[name_or_addr]
							 | 
						||
| 
								 | 
							
								    cdef uint64_t val = self.pack(addr, values, counter)
							 | 
						||
| 
								 | 
							
								    val = self.ReverseBytes(val)
							 | 
						||
| 
								 | 
							
								    return [addr, 0, (<char *>&val)[:size], bus]
							 |