I've been looking at the "sources" as well and have added a bit of documentation to my Python program detailing what the startup sequence is.
Read the comments imbedded in the program. Comments welcome
There is a lot of useful info in the JAD or jd decompiled sources, each are different and provide a different view of what the original .java files were.
I haven't dug into either the disassembled libseekware.so or what I got using objdump. Understanding armv7a assembly of a C++ program is not easy.
The camera initilization code corresponds to
Seek code at line 1017 of SeekwareLibrary.java:
protected void finalizeActivation(SeekwareDevice seekwaredevice)
# You will need to have python 2.7 (3+ may work, not tried)
# and PyUSB 1.0 (needs to be gotten as source from Github and installed as root)
# and PIL (Pillow fork, often in debian distros)
# and numpy (often in debian base distros)
# and scipy
# and Tkinter
# and ImageTk (part of Pillow but a seperate module)
# and maybe some other stuff
# You will probably have to run this as root unless you get your udev/mdev rules
# set up to allow the Seek device to be used by other than root.
# Many thanks to the folks at eevblog, especially (in no particular order)
# miguelvp, marshallh, mikeselectricstuff, sgstair, Fry-kun and many others
# for the inspiration to figure this out
# This is not a finished product and you can use it if you like. Don't be
# suprised if there are bugs as I am NOT a programmer..... ;>))
# There is also a lot of test code sprinkled about which probably doesn't work.
# Updated the USB send/receive mseeage code to use Fry-Kun's (sort of). And add
# a bit of error checking.
# There are also the beginnings of some documentation on the Seek init sequence.
import usb.core
import usb.util
import sys
from PIL import Image, ImageTk
import numpy
import colorscale # used to colorizing the image, be sure that colorscale.py is in the
# current directory
# Original colorscale.py from https://github.com/pklaus/python-colorscale
from scipy.misc import toimage
from scipy import ndimage
import Image
from numpy import array
import Tkinter
class App(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self,parent)
self.parent = parent
self.initialize()
# defs
def usbinit(self):
# find our Seek Thermal device 289d:0010
dev = usb.core.find(idVendor=0x289d, idProduct=0x0010)
# was it found?
if dev is None:
raise ValueError('Device not found')
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
assert ep is not None
return dev
#
# send_msg sends a message that does not need or get an answer
def send_msg(self,dev,bmRequestType, bRequest, wValue=0, wIndex=0, data_or_wLength=None, timeout=None):
assert (dev.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout) == len(data_or_wLength))
# alias method to make code easier to read
# receive msg actually sends a message as well.
def receive_msg(self,dev,bmRequestType, bRequest, wValue=0, wIndex=0, data_or_wLength=None, timeout=None):
zz = dev.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength, timeout) # == len(data_or_wLength))
return zz
# Some day we will figure out what all this init stuff is and
# what the returned values mean.
# Here are what the commands mean, still no clue about the passed params or return values:
# ("WINDOWS_TARGET", 0, 0);
# ("ANDROID_TARGET", 1, 1);
# ("MACOS_TARGET", 2, 2);
# ("IOS_TARGET", 3, 3);
# There seem to be 2 SeekOperationMode(s) 0 = Sleep, 1 = Run
# BEGIN_MEMORY_WRITE = 82;
# COMPLETE_MEMORY_WRITE = 81;
# GET_BIT_DATA = 59;
# GET_CURRENT_COMMAND_ARRAY = 68;
# GET_DATA_PAGE = 65;
# GET_DEFAULT_COMMAND_ARRAY = 71;
# GET_ERROR_CODE = 53;
# * GET_FACTORY_SETTINGS = 88;
# * GET_FIRMWARE_INFO = 78;
# GET_IMAGE_PROCESSING_MODE = 63;
# * GET_OPERATION_MODE = 61;
# GET_RDAC_ARRAY = 77;
# GET_SHUTTER_POLARITY = 57;
# GET_VDAC_ARRAY = 74;
# * READ_CHIP_ID = 54;
# RESET_DEVICE = 89;
# SET_BIT_DATA_OFFSET = 58;
# SET_CURRENT_COMMAND_ARRAY = 67;
# SET_CURRENT_COMMAND_ARRAY_SIZE = 66;
# SET_DATA_PAGE = 64;
# SET_DEFAULT_COMMAND_ARRAY = 70;
# SET_DEFAULT_COMMAND_ARRAY_SIZE = 69;
# SET_FACTORY_SETTINGS = 87;
# * SET_FACTORY_SETTINGS_FEATURES = 86;
# SET_FIRMWARE_INFO_FEATURES = 85;
# * SET_IMAGE_PROCESSING_MODE = 62;
# * SET_OPERATION_MODE = 60;
# SET_RDAC_ARRAY = 76;
# SET_RDAC_ARRAY_OFFSET_AND_ITEMS = 75;
# SET_SHUTTER_POLARITY = 56;
# SET_VDAC_ARRAY = 73;
# SET_VDAC_ARRAY_OFFSET_AND_ITEMS = 72;
# * START_GET_IMAGE_TRANSFER = 83;
# * TARGET_PLATFORM = 84;
# TOGGLE_SHUTTER = 55;
# UPLOAD_FIRMWARE_ROW_SIZE = 79;
# WRITE_MEMORY_DATA = 80;
# Only a few of the above (*) seem to be used in the normal startup sequence
# De-init the device
def deinit(self,dev):
msg = '\x00\x00'
for i in range(3):
self.send_msg(dev,0x41, 0x3C, 0, 0, msg) # 0x3c = 60 Set Operation Mode 0x0000 (Sleep)
# Camera initilization
def camerainit(self,dev):
try:
msg = '\x01'
self.send_msg(dev,0x41, 0x54, 0, 0, msg) # 0x54 = 84 Target Platform 0x01 = Android
except Exception as e:
self.deinit(dev)
msg = '\x01'
self.send_msg(dev,0x41, 0x54, 0, 0, msg) # 0x54 = 84 Target Platform 0x01 = Android
self.send_msg(dev,0x41, 0x3C, 0, 0, '\x00\x00') # 0x3c = 60 Set operation mode 0x0000 (Sleep)
ret1 = self.receive_msg(dev,0xC1, 0x4E, 0, 0, 4) # 0x4E = 78 Get Firmware Info
#print ret1
#array('B', [1, 3, 0, 0]) # version 1.3.0.0 firmware. This was captured a while ago and may not represent the current version.
ret2 = self.receive_msg(dev,0xC1, 0x36, 0, 0, 12) # 0x36 = 54 Read Chip ID
#print ret2
#array('B', [20, 0, 12, 0, 86, 0, 248, 0, 199, 0, 69, 0])
self.send_msg(dev,0x41, 0x56, 0, 0, '\x20\x00\x30\x00\x00\x00') # 0x56 = 86 Set Factory Settings Features
ret3 = self.receive_msg(dev,0xC1, 0x58, 0, 0, 0x40) # 0x58 = 88 Get Factory Settings
#print ret3
#array('B', [2, 0, 0, 0, 0, 112, 91, 69, 0, 0, 140, 65, 0, 0, 192, 65, 79, 30, 86, 62, 160, 137, 64, 63, 234, 149, 178, 60, 0, 0, 0, 0, 0, 0, 0, 0, 72, 97, 41, 66, 124, 13, 1, 61, 206, 70, 240, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 66, 0, 0, 2, 67])
self.send_msg(dev,0x41, 0x56, 0, 0, '\x20\x00\x50\x00\x00\x00') # 0x56 = 86 Set Factory Settings Features
ret4 = self.receive_msg(dev,0xC1, 0x58, 0, 0, 0x40) # 0x58 = 88 Get Factory Settings
#print ret4
#array('B', [0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 161, 248, 65, 63, 40, 127, 119, 60, 44, 101, 55, 193, 240, 133, 129, 63, 244, 253, 96, 66, 40, 15, 155, 63, 43, 127, 103, 186, 9, 144, 186, 52, 0, 0, 0, 0, 0, 0, 2, 67, 0, 0, 150, 67, 0, 0, 0, 0])
self.send_msg(dev,0x41, 0x56, 0, 0, '\x0C\x00\x70\x00\x00\x00') # 0x56 = 86 Set Factory Settings Features
ret5 = self.receive_msg(dev,0xC1, 0x58, 0, 0, 0x18) # 0x58 = 88 Get Factory Settings
#print ret5
#array('B', [0, 0, 0, 0, 255, 255, 255, 255, 190, 193, 249, 65, 205, 204, 250, 65, 48, 42, 177, 191, 200, 152, 147, 63])
self.send_msg(dev,0x41, 0x56, 0, 0, '\x06\x00\x08\x00\x00\x00') # 0x56 = 86 Set Factory Settings Features
ret6 = self.receive_msg(dev,0xC1, 0x58, 0, 0, 0x0C) # 0x58 = 88 Get Factory Settings
#print ret6
#array('B', [49, 52, 48, 99, 49, 48, 69, 52, 50, 78, 55, 49])
self.send_msg(dev,0x41, 0x3E, 0, 0, '\x08\x00') # 0x3E = 62 Set Image Processing Mode 0x0008
ret7 = self.receive_msg(dev,0xC1, 0x3D, 0, 0, 2) # 0x3D = 61 Get Operation Mode
#print ret7
#array('B', [0, 0])
self.send_msg(dev,0x41, 0x3E, 0, 0, '\x08\x00') # 0x3E = 62 Set Image Processing Mode 0x0008
self.send_msg(dev,0x41, 0x3C, 0, 0, '\x01\x00') # 0x3c = 60 Set Operation Mode 0x0001 (Run)
ret8 = self.receive_msg(dev,0xC1, 0x3D, 0, 0, 2) # 0x3D = 61 Get Operation Mode
#print ret8
#array('B', [1, 0])
# 11/25/2014-21:10 MDT no documentation of Seekware stuff below here... This will change.
...ken...
The program above is not complete and will not run.