DevWare Python

Overview

DevWare embeds Python as its built-in scripting language.

Within a Python script, access to the sensor and DevWare features is through built-in extension modules called Devware and ApBase (Note that this used to be Midlib which has been replaced by ApBase). Functions that correspond to ApBase API calls are in the ApBase module. (ApBase is the library that does all I/O to the sensor including register access and acquiring images. See the ApBase API document.) All other functions are in the DevWare module. The reason for the split is so scripts can work in other ApBase-based applications besides DevWare as long as they don't depend on DevWare-specific features.  

To enable Python in DevWareX, you will be prompted with the URL for the 64-bit version.
Here isthe direct link:
https://www.python.org/ftp/python/3.8.2/python-3.8.2-amd64.exe

You can manage the environment as well; see page Python Environment Selection for details.

There is a simple Python console window in DevWare. On the main window select the menu View -> Python Console. The output from executing Python code appears in the upper text box. Commands for immediate execution may be entered in the lower edit box. The command entry window keeps a command history; use the up and down arrows to select a previous command.

The usual way to run Python code within DevWare is to put the code in an ini file and execute it like any other ini file preset. It's also possible to send code to the Python interpreter through the COM interface and from a plug-in.

To run embedded Python from the COM interface, use the RunPython() method. See  DevWare COM Interface.

To run embedded Python from a plug-in, use the RunPython() callback. See the Plugin Dialog Development Guide.

Both INI file and Python samples can be found in the installation folder under "samples\Python_Samples" with a description found here.

Tutorial

This is a quick tutorial on using the Python extensions in DevWare. If you are familiar with DevWare ini file commands see also the Ini File Equivalents chapter below.

Python Console Window

DevWare has a simple Python console window. Select the menu item View->Python Console to show the window.

All output directed to stdout or stderr (print() calls and error messages) goes to the top part of the window. In the bottom portion of the window you can type any command or expression for immediate execution.

The Python input() function (sys.stdin.readline()) causes a small pop-up dialog to appear where the user can enter the requested data.

Python in Ini Files

You can put Python code in an ini file, and use the Presets dialog or User Toolbar to execute it.

There are two ways to embed Python in ini files. To execute single Python lines mixed with other ini file commands use a PYTHON= command.

[my preset]
REG= 0x3012, 0
PYTHON= print('set 0x3012 to 0')

Output from Python commands shows up in the Python Console window.

To execute a block of Python code of any size, create a preset with only Python in it. So the ini file interpreter knows to expect Python syntax instead of ini syntax you must have the string 'Python:' somewhere in the name of the preset.

[Python: clear some regs]
for addr in range(0x3600, 0x3800, 2):
    reg.reg(addr).value = 0

Python code executes in the context of the _main_ module. DevWare automatically does an import sys, import apbase and import devware, and adds the directory of the ini file to sys.path. It creates a variable called reg that gives convenient access to sensor registers (more on this shortly), and a variable called demo2 (if you are running on a DEMO2 or DEMO2X) or demo3 (if you are using a DEMO3 board) for camera board FPGA registers. You can easily create these variables in your own modules too.

If there is a preset called only [Python:], DevWare will automatically execute it when it loads the ini file. This gives you a convenient place to put additional import statements, function definitions, or any other one-time-execute code. You can use "Hidden:" as with other presets if desired.  Example:

[Python:]
import os.path
import re
def image_size_a(w, h):
    reg.PRI_A_IMAGE_WIDTH = w
    reg.PRI_A_IMAGE_HEIGHT = h
    reg.SEQ_CMD = 6

If there is a preset called [Python: Unload], DevWare will automatically execute it when the corresponding ini file window is closed, or when DevWare exits. This can be used to clean up background threads.

DevWare only executes [Python:] when the ini file is opened in a Presets window. In scripts you have to execute [Python:] explicitly if the file isn't in a window, or in applications outside of DevWare. 
You can load an ini file into a DevWare Presets window with: 
    devware.open_ini_file(inifilepath) 
This will run [Python:].

DevWare automatically creates a variable called __IniFileName. When the execution of an ini file preset begins, DevWare sets the contents of this variable to the full path to the ini file. This is useful for accessing other files in the same directory as the current ini file. Note that when execution of the preset ends, the variable reverts back to its previous value, so the variable is not meaningful if accessed from a background thread that remains running after the preset that launched it is finished. If the ini file path is needed in a thread function, then it must be passed to the thread function as a parameter.

Aborting a running script

If a Python script is running in the main DevWare UI thread, then the DevWare user interface is not responsive while the script is running. This is the typical case when the user initiates a script in an ini file. In order to allow interrupting a script and aborting its execution, DevWare includes a mechanism which monitors the amount of time the script is running. If the script runs for more than the timeout time, DevWare will show a dialog window allowing the user to abort it. This is useful for cases where the script is running longer than intended, or is in an infinite loop.

In order for this option to work, the library signal has to be imported. This can be done either at the beginning of the individual script, or at the beginning of the default Python preset [Python:] (see section Python in Ini Files).

The following example shows a script with an infinite loop, which can be aborted by the user if the timeout has been set:

[Python: infinite loop]
import signal
i = 0
while i < 1:
    i = 0

You set the timeout value by using the DevWare option variable Script Timeout: devware.setoption('Script Timeout', 10). Assigning this variable an integer number would set the timeout to the specified value in seconds. It is not possible to set a timeout in fractions of seconds.

Disable the timeout completely by setting the variable to the value 0.

Once the value has been set, it can always be modified to a new timeout value at any time during the execution of the Python script. DevWare checks whether a different timeout value has been set every 1 second.

ApBase Module Overview

ApBase is the library that all DevSuite applications use to access the camera devices. The apbase module provides classes that represent the physical devices on the camera or emulator platform, and classes to represent registers and register bitfields. I/O to the devices is performed by using methods and attributes on instances of these classes that correspond to specific chips and registers.

Accessing Registers

To read or write a register, create an apbase.Register object connected to the desired register and then get or set its value attribute. To illustrate, this example explicitly calls the apbase.Register constructor to create a Register object, and then writes to the register.

blacklevel = apbase.Register(symbol='DATA_PEDESTAL').value # read
apbase.Register(symbol='DATA_PEDESTAL').value = 42 # write


By default the apbase.Register() constructor looks for registers on the sensor. You can also specify another chip (if there's a chip data (.cdat) file loaded for it). You can alternately specify the register by address instead of name.

Explicitly calling the apbase.Register constructor is cumbersome, so for convenience there is the RegisterSet class. The RegisterSet class has helpful attributes and methods for constructing Register objects and writing to registers with short, simple syntax.

A RegisterSet object automatically has attributes corresponding to each of the registers. The predefined variable reg is the register set for the sensor, so reg.DATA_PEDESTAL implicitly calls the Register constructor to construct a Register object for the DATA_PEDESTAL register. The above example can be written as:

blacklevel = reg.DATA_PEDESTAL.value # read
reg.DATA_PEDESTAL.value = 42 # write

As further shorthand, assigning to the register symbol attribute is equivalent to assigning to the value (or float_value) attribute of the register object.

reg.DATA_PEDESTAL = 42

But understand that reg.DATA_PEDESTAL on the right hand side of an assignment or in an expression is the Register object. So

a = reg.DATA_PEDESTAL

sets a to the Register object, not the value of the register. To use the value of the register in an assignment or any expression, either use the value or float_value attribute, or explicitly cast the Register object to an int or float.

a = int(reg.DATA_PEDESTAL)

Note: ApBase Caches Register Values

ApBase keeps the last value read or written to a register in a cache. As an optimization, the value attribute does a cached read. That is, it normally just returns the last read or written value without doing any I/O to the device. So doing a register read like this is very cheap and there is no need for you to cache register values in your Python code. But sometimes you do need to re-do I/O, for example to read a status register that changes automatically. In that case use the uncached_value attribute.

a = reg.JPEG_STATUS.uncached_value # force reading the hardware

Using Register Objects

Registers as Python objects is very useful. For example you could write generic functions that can operate on any kind of register. This function sets a register to its default value as defined in the sensor data file.

def restore_default(rr):
    rr.value = rr.default

restore_default(reg.DATA_PEDESTAL)

Register Data Type and float_value

A Register object has both value and float_value attributes. The difference is the value attribute is the bits in the register as an unsigned integer, but the float_value translates from the register bits to a numerical value in floating point according to the data type of the register. If the register data type is unsigned integer, then value and float_value do the same thing, except float_value returns a Python float number. But if the data type is something else then float_value interprets the bits differently than value.

For example suppose firmware variable AWB_CCM_0 is 16-bit 2's complement signed fixed point with 8 fraction bits (the 'fixed8' data type). Then

reg.AWB_CCM_0.float_value = 1.75

assigns 0x01C0 to the variable. In an expression, casting a Register object to an int is the same as getting the value attribute, and casting a register to a float is the same as getting the float_value attribute.

x = reg.AWB_CCM_0.float_value
is equivalent to
x = float(reg.AWB_CCM_0)

There is also the uncached_float_value attribute that does an uncached read and a conversion to floating point.

Using the shorthand of setting a Register attribute of a RegisterSet object will use either the value or float_value depending on whether the right hand side is an int or float type.

reg.AWB_CCM_0 = 1.75
is equivalent to
reg.AWB_CCM_0.float_value = 1.75

and

reg.AWB_CCM_0 = 322
is equivalent to
reg.AWB_CCM_0.value = 322

Note that
reg.AWB_CCM_0 = x

may use either value or float_value depending on what data type x has when the statement is executed. That may be how you want it, but if you need it unambiguous either cast the right hand side to int or float, or use the value or float_value attribute.

reg.AWB_CCM_0 = float(X)
or
reg.AWB_CCM_0.float_value = X

The data type is held in the datatype attribute of a register.

>>> reg.AWB_CCM_0.datatype
'fixed8'

You can also see the data type in DevWare at the bottom of the Register panel.

Register Bitfields

Similar to the Register class is the Bitfield class that represents a bitfield of a register. A Register object automatically has an attribute corresponding to each bitfield defined in the sensor data file.

reg.IMAGE_ORIENTATION.VERT_FLIP = 1 # write bitfield VERT_FLIP
vf = reg.IMAGE_ORIENTATION.VERT_FLIP.value # read bitfield

img_orien = reg.IMAGE_ORIENTATION # Register object
img_orien.VERT_FLIP = 0 # write bitfield

vf = img_orien.VERT_FLIP # Bitfield object
print(vf.value) # read bitfield (and print)

You can also construct a Bitfield object with an explicit mask if needed by calling the Bitfield constructor explicitly. The parameters to the Bitfield constructor are the parent register and the mask.

apbase .Bitfield(reg.AS_ALGO, mask=0xF0).value = 0 # write bitfield

For convience the Register class has a method called bitfield() that constructs a Bitfield object. You could write the above as

reg.AS_ALGO.bitfield(0xF0).value = 0

Bitfields can also have data types, and support both the value and float_value attributes.

Writing to a Bitfield always uses an uncached read in the read-modify-write cycle.

Iterating Over All Registers on a Device

A RegisterSet object is iterable (Python lingo). It iterates over the registers in the set. For example, this will loop over all sensor registers and print the symbolic name.

for rr in reg:
    print(rr.symbol)

Register objects are also iterable and iterate over their bitfields. This prints out the names of all registers on the sensor with all bitfields of each register, as defined in the sensor data file.

for r in reg:
    print(r.symbol)
    for b in r:
         print(' ', b.symbol)

Constructing a Register from an Address

You may prefer to specify a register by its address instead of its symbolic name, as a personal preference, or if the register is not in the sensor data file. The RegisterSet class has methods reg(), var() and sfr() to construct Register objects by address with simple syntax.

SFR in this context really just means physically, as opposed to logically, addressed memory on the SOC. Any physically addressed memory can be accessed with reg.sfr(). On SOCs that have multiple physical regions the PHY_REGION has to be specified before the address (similar to the driver number for a VAR.)

reg.reg(0x301A).value = 0x10C8
reg.var(3, 0x1E).value = 0x3F # driver 3, offset 0x1E
reg.sfr(0, 0x1400).value = 0x8044 # patch RAM, address 0x1400

Camera, Sensor and Chip Classes

The other classes are Camera, Sensor and Chip. The Camera represents the whole device. The Sensor is the sensor or SOC chip, or companion chip + sensor combination, as defined by the sensor data file. The Chip objects represent any additional chip data files that may be loaded corresponding to other chips on the I2C bus in the system, for example the DEMO2 FPGA.

The Camera constructor takes only an integer argument to indicate which camera device. Under DevWare camera 0 always corresponds to the currently selected camera. If there are other cameras attached to the system, they are accessible with indices from 1 to apbase.num_cameras – 1.  The parameter is optional, and defaults to the currently selected camera.

>>> apbase.Camera().name
'Aptina Imaging DEMO2'

The camera object has a sensor attribute that returns the Sensor object, and chip() method that returns a Chip object given a chip number.

>>> apbase.Camera().sensor.name
'A-3132SOC'

>>> apbase.Camera().chip(0).name
'DEMO2 B5'

Sensor and Chip objects have an attribute called reg that returns the RegisterSet for the device. The reg variable used in most of the examples above was created by

reg = apbase.Camera().sensor.reg

Capturing an Image from the Camera

To capture an image use the grab_frame() method of the Camera. Grab_frame() returns a 2-tuple with the status code and a bytearray of the image data.

statuscode, img = apbase.Camera().grab_frame()

A status code of apbase.MI_CAMERA_SUCCESS (0) indicates success. Even if the status code is not 0, the bytearray will hold whatever data was received.

The colorpipe() method can convert the raw image to RGB. Colorpipe() returns a 4-tuple with the RGB image as a bytearray, and the width, height and bit-depth of the RGB data. This is the same conversion used in the DevWare display window.

rgb,w,h,d = apbase.colorpipe(img)

Other Apbase Methods

The getstate() and setstate() methods get and set ColorPipe variables. This is the same as the STATE= ini file command.

apbase.setstate(‘Contrast’, 25)

The image() method sets the image dimensions and type. Normally ApBase can determine these automatically, this is an override useful especially during development or when a sensor is new and the DevWare support is not fully worked out yet.

The load_preset() method executes a preset from an ini file.

The apbase module also implements a Console object which is linked to sys.stdin, sys.stdout and sys.stderr. In DevWare, calls to the write() method on stdout or stderr cause the data to appear in the Python Console window. Calls to stdin.readline() cause a small pop-up dialog to appear where the user can enter the data.

Devware Module Overview

The devware module consists mainly of methods based on the COM port methods. See also DevWare COM Interface.

The getstate() and setstate() methods get and set ColorPipe variables. This is the same as the STATE= ini file command.

devware.setstate('Contrast', 25)

The getoption(), setoption(), getoption_str(), and setoption_str() methods are the same as the COM port functions and set various DevWare modes and features.

devware.setoption('User Toolbar Show', 1)

The get_mouse_selection() and set_mouse_selection() methods get and set the Mouse Selection type and area. Get_mouse_selection() returns a tuple with 5 values.

sel, x1, y1, x2, y2 = get_mouse_selection()

sel can be 'off', 'row', 'column', 'rectangle', or 'point'. For 'row' only y1 is relevant, for 'column' only x1 is relevant, and for 'point' only x1 and y1 are relevant.

The image() method sets the image dimensions and type. Normally DevWare can determine these, this is an override useful especially during development or when a sensor is new and the DevWare support is not fully worked out yet.

The load_preset() method executes a preset from an ini file.

The upload_firmware() method loads firmware or firmware patches. Same as the COM function.

The upload_image_file() method loads a test image to a supported emulator platform. Same as the COM function.

The command() method sends a WM_COMMAND message to the DevWare main window. See the COM port document.

The stop() method stops the video streaming background threads if they are running.

The begin_access_regs() and end_access_regs() methods make accessing registers while images are streaming more efficient with drivers that don't support simultaneous register access and image capture.

The devware module also implements a Console object which is linked to sys.stdin, sys.stdout and sys.stderr. Calls to the write() method on stdout or stderr cause the data to appear in the Python Console window. Calls to stdin.readline() cause a small pop-up dialog to appear where the user can enter the data.

Threading

DevWare has three threads, the main thread which runs the user interface, and if video is streaming then two background threads, one that captures images from the camera (the camera thread) and one that does the image processing and displays the images (the display thread).

When the user runs an ini file preset, DevWare shuts down the camera and display threads. While the ini file is executing DevWare is a single-threaded application, and the script author need not worry about concurrency or other multi-threading issues.

It may be desirable to run Python code in a thread concurrently with the other DevWare threads. In that case the Python threading module can be used to create a new thread and run Python code in it. Put the code to execute as a thread in a function, and call the function indirectly through threading.Thread().start(). Example:

[Python:]
import threading
def test_run(initial_it, n):
     reg.COARSE_INTEGRATION_TIME = initial_it
     for i in range(0, n):
         apbase.delay(1000)
         reg.COARSE_INTEGRATION_TIME.value += initial_it

[Python: Thread Test]
threading.Thread(target= test_run, args= (60,20)).start()

When the user invokes [Python: Thread Test] in the Presets dialog, the DevWare UI thread shuts down the camera and display threads, executes [Python: Thread Test] (which only creates a new thread and then finishes), and then resumes the camera and display threads. Simultaneously the new thread begins executing and remains alive after [Python: Thread Test] has finished. The 'test_run' thread increments the COARSE_INTEGRATION_TIME register 60, 120, 180, … 1200 every 1000ms until finished, which takes about 20 seconds. When the function exits the thread self-destructs.

If there is a preset called [Python: Unload], DevWare will automatically execute it when the corresponding ini file window is closed, or when DevWare exits. This can be used to clean up background threads.

Subprocesses

If the use of a Subprocess is necessary instead of a thread, "sys.prefix" can be used to ensure that the same version of Python is being used. 
An example;

import os
import sys
import subprocess

command = [os.path.join(sys.prefix, 'python.exe'), '–version']
output = subprocess.check_output(command, shell=True)
print(output)

Results in:

>>> b'Python 3.9.4\r\n'

Ini File Equivalents

This section lists ini file commands with the Python code that does the same or similar thing. It will illustrate how to do common operations.

On the left are example ini file commands, and the equivalent Python is on the right. Keep in mind that Python is much more flexible than the ini commands. Where an ini command required a numerical constant, Python will allow any expression. Python has much more flow control, functions with parameters, user-defined classes and so on.

This is the recommended way to write a register, variable or bitfield.

INI File CommandsPython Script
FIELD_WR= OUTPUT_FORMAT_TEST, 256reg.OUTPUT_FORMAT_TEST = 256
FIELD_WR= SEQ_CAP_MODE, VIDEO, 1reg.SEQ_CAP_MODE.VIDEO = 1

If the data type is defined, you can use floating point values and Python will translate to the right value accordingly.This example has fixed8 (signed with 8 fraction bits) CCM settings.

INI File CommandsPython Script
FIELD_WR=CAM1_AWB_CCM_L_0, 0x0180 reg. CAM1_AWB_CCM_L_0 = 1.5
FIELD_WR=CAM1_AWB_CCM_L_1, 0xFF7A reg. CAM1_AWB_CCM_L_1 = -0.523
FIELD_WR=CAM1_AWB_CCM_L_2, 0x0018reg. CAM1_AWB_CCM_L_2 = 0.094

On older sensors that have multiple pages of 8-bit addressed registers and an ADDR_SPACE_SEL register, the reg.reg() method takes two parameters. On newer sensors with a 16-bit register address space reg.reg() takes one parameter. It is an error to use the wrong number of parameters.

INI File CommandsPython Script
REG= 0x3084, 0x2409 (no register page) reg.reg(0x3084).value = 0x2409
REG= 1, 0x08, 0x0158 (with register page)reg.reg(1, 0x08).value = 0x0158


Same as REG= but use the bitfield() method to construct a Bitfield object.

INI File CommandsPython Script
BITFIELD= 0x001A, 0x0200, 1reg.reg(0x001A).bitfield(0x0200).value = 1
BITFIELD= 0, 0x23, 0x100, 1reg.reg(0, 0x23).bitfield(0x100).value = 1


Note that the size of the variable is determined by the sensor data file. If the variable is not defined then an optional size in bits can be passed as the third argument. It defaults to 16 bits wide.

INI File CommandsPython Script
VAR= 18, 0x126, 1reg.var(18, 0x126).value = 1

VAR8 forces an 8-bit data transaction. The Python is not quite equivalent because if the variable is defined in the sensor data file, Python will use the data size in the sensor data file and ignore the data size parameter.

INI File CommandsPython Script
VAR8=15, 0x0C, 0reg.var(15, 0x0C, 8).value = 0

This writes to MCU memory using the physical, rather than logical, addressing. SFR8 is analogous to VAR8. If the SOC supports multiple physical regions, then the physical region must be the first parameter. After the address you can specify an optional size in bits. The default is 16 bits.

INI File CommandsPython Script
SFR= 0x1078, 0xFFFFreg.sfr(0x1078).value = 0xFFFF


If you set a register to a list of values Python does a burst write. This only works for simple registers and SFR (physically addressed) memory.

INI File CommandsPython Script
REG_BURST= 0x990, 0x3C3C, 0x3C3C, 0x3C5F, 0x4F30, 0xED08, 0xBD61, 0xD5CE, 0x4CDreg.reg(0x990).value = [0x3C3C, 0x3C3C, 0x3C5F, 0x4F30, 0xED08, 0xBD61, 0xD5CE, 0x4CD]

or (if 0x990 is MCU_DATA_0)

reg.MCU_DATA_0 = [0x3C3C, 0x3C3C, 0x3C5F, 0x4F30, 0xED08, 0xBD61, 0xD5CE, 0x4CD]

The SERIAL_REG command is for I2C write to any arbitrary device address with specified register address size and data size. There is equivalent Python syntax by explicitly calling the apbase.Register constructor, but there may be a better way.
If there is a chip data file loaded for the chip, you can access the register by its name through the RegisterSet object for the chip
 
chipreg = apbase.Camera().chip(1).reg
chipreg.CONTROL_REG = 0x123
 
If the register is on the DEMO2 or MIDES FPGA you can use the predefined demo2 or mides RegisterSet variables. If there is no chip data file (or even if there is), you can create a Python variable for the Register object and use that.
 
ctrl_reg = apbase.Register(ship_addr=0x38, addr=0x04, addr_size=8, data_size=16)
ctrl_reg.value = 0x18
 
You can also do bitfield writes in Python using the bitfield() method of the Register class, or by named bitfield.

INI File CommandsPython Script
SERIAL_REG= 0x64, 0x25, 0x18, 8:16apbase.Register(ship_addr=0x64, addr=0x25, addr_size=8, data_size=16).value = 0x18

or (since this example is on the DEMO2)

demo2.SP_CONTROL = 0x18


Delay in milliseconds.

INI File CommandsPython Script
DELAY= 50apbase.delay(50)

Set a DevWare internal variable. You can also set so-called DevWare Option variables with devware.setoption().

INI File CommandsPython Script
STATE= Display Zoom Percent, 50apbase.setstate('Display Zoom Percent', 50)

Execute a file preset from an ini file. If no filename is given, the devware.load_preset() method will load from the currently executing ini file, or if that can't be determined, the main ini file. Also consider defining a function entirely in Python instead of using an ini preset.

INI File CommandsPython Script
LOAD= AWB Settings apbase.load_preset('AWB Settings')
LOAD= mysettings.ini, New CCMdevware.load_preset('mysettings.ini', 'New CCM')

Present a multiple choice to the user. Python is more flexible in that it can do anything following the user's selection, it's not limited to executing a preset.

INI File CommandsPython Script
PROMPT= "Choose Mode", "Parallel", LOAD=Init Parallel, "MIPI", LOAD=Init MIPI

sel = apbase.multiple_choice('Choose Mode', ['Parallel', 'MIPI'])
if sel == 1: initParallel()
if sel == 2: initMipi()

 Register polling and testing: Python, of course, has looping and flow control constructs far beyond what you can do in an ini file. If you do a lot of similar POLLs, you could write a function to make your code more compact.

INI File CommandsPython Script
POLL_FIELD= SEQ_CMD, !=0, DELAY=10, TIMEOUT=50timeout = 0
while (reg.SEQ_CMD.uncached_value != 0 and timeout < 50):
apbase.delay(10)
timeout += 1

POLL_VAR similarly, but with reg.var().

INI File CommandsPython Script
POLL_REG= 0x3F, 0xFFFF, >8, DELAY=50, TIMEOUT=5timeout = 0
while (reg.reg(0x3F).uncached_value > 8 and timeout < 5):
apbase.delay(50)
timeout += 1

The ini file syntax required the if and else blocks to be in presets. In Python they can be inline, or in functions. Also there is much more flexibility in expressing the condition in Python.

INI File CommandsPython Script
IF_FIELD= SHUTTER_WIDTH_LIM_AE, >0x100, LOAD=Night mode, ELSELOAD=Day modeif (reg.SHUTTER_WIDTH_LIM_AE.value > 0x100):
night_mode()
else:
day_mode()
IF_REG= 2, 0x37, 0xFFFF,== 0x100, LOAD=Night mode, ELSELOAD=Day modeif (reg.reg(2, 0x37).value == 0x100):
night_mode()
else:
day_mode()

The error message will go to the Python Console window.

INI File CommandsPython Script
ERROR_IF= COMMAND_REGISTER, HOST_COMMAND, !=0, "Command failed"assert reg.COMMAND_REGISTER. HOST_COMMAND.value == 0, 'Command failed'

Similarly for FAR2.
To access a FAR register by name use apbase.Register(symbol='FAR1.DARK_CONTROL').value
Unfortunately, the pre-existing practice of using a dot in the names of FAR registers currently precludes using the reg.REGNAME syntax.

INI File CommandsPython Script
FAR1= 0, 0x3044, 0x0020, 1apbase.Register(addr_type='FAR1', addr=0x3044).bitfield(0x0020).value = 1

Datatypes are defined in the sensor data file now, but you can also set or change datatype, minimum, and maximum within Python if needed

INI File CommandsPython Script
DATATYPE= HUE_ANGLE, signed, RANGE=-22:22reg.HUE_ANGLE.datatype = signed
reg.HUE_ANGLE.minimum = -22
reg.HUE_ANGLE.maximum = 22

This works exactly the same as the ini command

INI File CommandsPython Script
LOG= "// White balance settings"apbase.log('// White balance settings')

This is only interpreted by the User Toolbar to set a button icon. In Python use the same syntax but in a comment. There must be no space between # and icon.
See "INI File Users Guide" for usage details for each command.

INI File CommandsPython Script
ICON= blue star#icon = blue star
TOOLTIP = "Enable/Disable HDR"#tooltip = "Enable/Disable HDR"
SHORTCUT= Ctrl+1#shortcut = Ctrl+1
MENUITEM = "Linear 1080p ...#menuitem = "Linear 1080p ...

This works exactly the same as the ini command.  Note; "context" parameter is optional.

INI File CommandsPython Script
IMAGE= 640, 480, YCBCR, 0apbase.image(640, 480, 'YCBCR', context=0)

ApBase load_prom() cannot load software settings (SWCCM, SWSTEREO, etc.).

INI File CommandsPython Script
LOAD_PROM= 0xA8, PGAapbase.Camera().load_prom(0xA8, 'PGA')

SAVE_IMAGE by default saves in the DevWare image capture directory. The example code above shows how to get the directory using getoption_str().

INI File CommandsPython Script
SAVE_IMAGE= capture.rawret, img = apbase.Camera().grab_frame()
savedir = devware.getoption_str('Capture File')
savedir = os.path.dirname(savedir)
savename = os.path.join(savedir,'capture.raw')
with open(savename, 'wb') as f:
f.write(img)

SAVE_REGS by default saves in the DevWare image capture directory. The example code above shows how to get the directory using getoption_str(). SAVE_REGS also writes the data as ini file commands. In Python you could of course use any format you want.

INI File CommandsPython Script
SAVE_REGS= regdump.txtsavedir = devware.getoption_str('Capture File')
savedir = os.path.dirname(savedir)
savename = os.path.join(savedir,'regdump.txt')
with open(savename, 'wt') as f:
print('[Saved Registers]', file=f)
for rr in reg:
print('FIELD_WR=",rr.symbol,',',rr.value, file=f)

This example uses a wildcard to save only registers with AWB in the name somewhere. Any criterion can be used.

INI File CommandsPython Script
SAVE_REGS= regdump.txt, AWBsavename = os.path.join(savedir,'regdump.txt')
with open(savename, 'wt') as f:
for rr in reg:
if (re.match('.*AWB', rr.symbol)):
print('FIELD_WR=',rr.symbol,',',rr.value, file=f)

All camera modes are exposed as attributes on a Camera object. Some others are ALLOW_FAR_ACCESS, PIXCLK_POLARITY, SENSOR_POWER, SENSOR_RESET, SHIP_SPEED, DIRECT_VAR_ACCESS.

INI File CommandsPython Script
 XMCLK= 24000000 apbase.Camera().OUTPUT_CLOCK_FREQ = 24000000



ApBase Module Reference

See also the ApBase API Document

Camera Class

The Camera class represents the whole demo board or emulator board. .

Constructor

Camera(index)

The parameter is which physical camera, and must be from 0 to apbase.num_cameras - 1.
Under DevWare camera 0 is always the camera that is currently selected in DevWare. Other cameras are accessible with indices from 1 to apbase.num_cameras - 1

The parameter is optional, and defaults to the currently selected camera.

Camera(filename)

Create an in-memory camera object from the filename. The file can be an image or video, or a sensor data file. If it's an image or video, grab_frame() will retrieve the pixel data. This provides a convenient way to load an image file into Python. If it's a sensor data file, the Camera object is populated with the sensor and register information from the file, but no I/O is possible.


Attributes

sensor

RO

The Sensor object for the camera. None if there is no sensor.

name
product_name

RO

Main board name. Ex: 'Aptina Imaging DEMO3'.

num_chips

RO

Number of additional chips, defined by chip data files from board_data directory. Normally at least one for the FPGA on the camera board.

version
product_version

RO

Normally the FPGA version. Ex: 0x43

serial_number
product_serial_number

ROMain board serial number; 10 digits in length

firmware_version

RO

Normally the product_id in the upper 16 bits and the firmware version in the lower 16 bits. Ex: 0x10070025.

product_id

RO

Normally the USB product ID (PID), one of the mi_product_ids constants. For a thrid party board it could be anything.

serdesR0If present, the product name and model number

All mi_modes

RW

All camera modes are exposed as attributes. Getting the attribute calls ap_getMode() and setting the attribute calls ap_setMode(). Always an integer value. Example:
apbase.camera().SHIP_SPEED = 100


Methods

chip(index)
chip(name)

Returns a Chip object for the specified chip. Parameter can be an integer index or a string name.
Index must be from 0 to camera.num_chips – 1.
Name must match the name of a defined chip.
Ex: hssa = camera.chip('HSSA Deserializer')

update_frame_size(width, height, bitsperclock, clocksperpixel)

Forces new image width and height, and new bits-per-clock and clocks-per-pixel values for the camera. If any parameter is 0 or omitted the current value is kept. In DevWare, values inconsistent with the current image type can cause a crash; prefer devware.image() instead.

grab_frame()

Attempts to grab a single image from the camera (call mi_grabFrame()). Returns a tuple with the first member an integer return code, and the second member a bytearray object with the raw binary data. The return code is one of the mi_error_code constants. MI_GRAB_FRAME_ERROR is usually a timeout. Other errors are usually because of a mismatch between the current settings for the image dimensions or image type and what the sensor is really doing.
Example:
returncode, img = camera.grab_frame()

invalidate_reg_cache()

Discard all cached register values. DevWare normally does this automatically as needed, such as after a reset or SOC command that will change many registers and variables. However there may be circumstances where you need to call it explicitly, such as for a device that DevWare does not recognize.

getmode(mode)

Get the value of a camera mode by mode ID number. Equivalent to ap_getMode().

setmode(mode, value)

Set the value of a camera mode by mode ID number. Equivalent to ap_setMode().

getgpio(pin)

Get the current state of a GPIO pin on the camera board.
setgpio(pin, value)Set the state of a GPIO pin on the camera board. 0 for output low, 1 for

output high, and 2 for high impedence (input).

probe_far_bus()

Enumerate ISP bus master. For ICP-HD call this at the appropriate point in the startup sequence.

load_prom(ship_addr, type, label=label, dest=address)

Load sensor settings from the headboard EEPROM. Ship_addr is the base address of the EEPROM. Type is one of 'PGA', 'CCM', or 'SCRATCHPAD'. Label is an optional label to load a specific setting. Dest is memory address, only used for SCRATCHPAD.
Example:
apbase.Camera().load_prom(0xA8, 'PGA', label='FACTORY')

refresh_sensor_file(filename)

Reload the register list from a sensor data file. This is intended to be used after loading a firmware patch that added new variables.

send_command(cmd, param_pool)

Sends a Host Command.

cmd is the command number
param_pool is the command result data as a bytearray 

Returns a tuple with the first member an integer command statuscode, and the second member a bytearray of the command result data


Sensor Class

The Sensor class represents the sensor or SOC chip. In the case of an ISP (AP1300 or similar), it represents the ISP and the attached sensors as a group. Other chips on the same I2C bus as the sensor are represented by Chip objects. The data comes from the sensor data file. 

Constructor

Normally you would construct a Sensor object using the sensor attribute of a Camera object. However the Sensor constructor can be called directly.

Sensor(camera=cam)

Returns a Sensor object given the parent Camera object. Same as cam.sensor.

Sensor(cameranum=index)

Returns a Sensor object given the index of a camera device. Same as Camera(index).sensor.


Attributes

reg

Returns a RegisterSet object that can be used to conveniently access the sensor registers.

name
sensor_name

Sensor name. Ex. 'A-3132SOC'.

version_name

Sensor version as a string. Ex: 'REV2'

version

Sensor version as an integer. Ex: 2

minor_versionSensor minor version as an integer. Ex: 1

part_number

Sensor part number as a string. Ex: 'MT9T112'

product_variantSensor product variant. Ex: ‘Clarity+’

file_name

Sensor data file name. For a physical sensor, this is the .xsdat file. For bitmap or video file pseudo-sensor, it's the image or video file.

base_addr
ship_addr

Sensor SHiP base address. Ex: 0x78. Read/write.

num_regs

Number of registers.

addr_size
reg_addr_size

Width of a register address in bits. Usually 8 or 16.

data_size
reg_data_size

Width of a register in bits. Usually 8 or 16.

width

Current image width. To change use apbase.image() for now.

height

Current image height. To change use apbase.image() for now.

image_type

Current image type as a string. To change use apbase.image() for now.

full_width

Nominal full image width of sensor.

full_height

Nominal full image width of sensor.

pixel_bits

Significant bits per pixel.

pixel_bytes

Bytes per pixel in memory.

fuse_idFuse ID of sensor.
fuse_id_far1Fuse ID of ISP's Sensor #1.
fuse_id_far2Fuse ID of ISP's Sensor #2.

All Sensor attributes are read-only unless otherwise noted.

Methods

There are no methods.

Chip Class

The Chip class represents an addition chip on the I2C bus, defined by a chip data file (from the board_data directory). 

Constructor

Normally you would construct a Chip using the chip() method of a Camera object. However the Chip constructor can be called directly.

Chip(camera=cam, index=j)

Construct a Chip from a given parent Camera object and a chip index. The index defaults to 0. Same as cam.chip(j). .

Chip(cameranum=c, index=j)

Construct a Chip from a given parent camera index and chip index. Both cameranum and index default to 0. Same as Camera(c).chip(j)..


Attributes

reg

Returns a RegisterSet object that can be used to conveniently access the chip registers.

name
chip_name

A chip name from the chip data file. Ex: 'DEMO2 B5'.

base_addr

SHiP base address. Ex: 0x64.

num_regs

Number of registers.

addr_size

Width of a register address in bits.

data_size

Width of a register in bits.

All Chip attributes are read-only.

Methods

There are no methods.

RegisterSet Class

The RegisterSet class is a convenience class for constructing Register objects.

See the Tutorial chapter, and the Register Class section for more information and examples. The pre-existing variable reg is a RegisterSet object created by reg = apbase.Camera().sensor.reg.

Constructor

Normally you would construct a RegisterSet object with the reg attribute of a Sensor or Chip object, but the constructor can be called directly.

RegisterSet(parent=camera, chipnum=i)

Construct a RegisterSet with the given parent Camera and an index indicating which chip. Chipnum = -1 indicates the sensor. Under DevWare the parent is optional and defaults to the currently selected camera. The chipnum is optional and defaults to -1.

RegisterSet(parent=sensor)

Construct a RegisterSet corresponding to the given Sensor object.

RegisterSet(parent=chip)

Construct a RegisterSet corresponding to the given Chip object.


Attributes

num_regs

RO

The number of registers.

All register names

RW

The symbolic names of all the registers defined in the sensor data or chip data file become attributes of the RegisterSet object.
Getting the attribute constructs a Register object. To read the register get one of the value attributes of the Register object.
Ex: dp = reg.DATA_PEDESTAL.value
Setting the attribute constructs a Register object and sets the value or float_value attribute of the Register object depending on whether the value is a float or not.
Ex: reg.DATA_PEDESTAL = 42
(Similarly, the bitfields of a register are attributes of a Register, so for example set a bitfield like reg.READ_MODE.LOW_POWER = 1.)


Methods

exists(symbol)

Returns True or False depending on whether the named register exists.

exists(rsymbol, bsymbol)

Returns True or False depending on whether the named register/bitfield exists.

reg(symbol)

Construct a Register object by symbolic name lookup.

reg(addr, bitwidth)
reg(addr_space, addr, bitwidth)

Construct a Register object that corresponds to a hardware register address. If the device is a sensor that has multiple pages of registers, the addr_space parameter is required. The bitwidth parameter is optional and defaults to the natural register width of the device.

var(driver, offset, bitwidth)

Construct a Register object that corresponds to a firmware variable address. The bitwidth parameter is optional and defaults 16 bits.

sfr(addr, bitwidth)
sfr(phy_region, addr, bitwidth)

Construct a Register object that corresponds to a physical RAM address. If the device is a sensor that has multiple physical memory regions, the phy_region parameter is required. The bitwidth parameter is optional and defaults to the natural register width of the device.


Looping Over All Registers

The RegisterSet object is iterable, and the iteration produces each of the registers defined for the parent device. In other words, if reg is a RegisterSet object, the following will loop over all registers of the device.
for rr in reg:
    print(rr.symbol)

Register Class

The Register class represents a hardware register, firmware variable, sensor SFR, sensor memory location, or any other type of register that is supported by apbase.

Constructor

In most cases you would construct a Register object implicitly using a RegisterSet method or attribute. It's possible to call the constructor explicitly when needed, such as when specifying the SHiP base address to access any arbitrary device on the bus.

A register is specified by its symbolic name or address, and a parent object. The parent can be a Sensor or Chip object, possibly specified as a Camera object and chip index number.

You can specify any arbitrary device and register location accessible by I2C, even if the device is not defined by any Sensor or Chip objects. In this case you would not specify a parent object, but instead provide the SHiP base address, register address size and register data size.

If there is a parent object, but the register is not defined in the parent's sensor data or chip data file, then you can specify a span or bitwidth for it. Otherwise the values come from the file.

Register(parent=camera, chipnum=chip, ...)

Specify parent as camera and chip number. Under DevWare the parent defaults to the currently selected camera. The chipnum defaults to -1 indicating the sensor.

Register(parent=sensor, ...)

Specify the parent as the given Sensor object.

Register(parent=chip, ...)

Specify the parent as the given Chip object.

Register(..., index=i)

Select the i'th register in the parent's sensor data or chip data file.

Register(..., symbol=name)

Select a register in the parent's sensor data or chip data file by symbolic name.

Register(..., addr=addr, addr_space=space, addr_type=type, span=span)

Identify the register by its address, address space (optional, defaults to 0) and address type (optional, defaults to 'REG').
The address type can be 'REG', 'VAR', 'SFR', 'MEM', 'IND', 'FAR1' or 'FAR2'.
The span can also be specified to indicate the total width. For memory the span is in bytes. For registers it's in the natural register size of the device. If the register is defined in the parent's sensor data or chip data file then the width is taken from there and the span parameter is ignored.

Register(ship_addr=base, addr_size=asize, data_size=dsize, addr=addr)

No parent. Instead explicitly specify the SHiP base address, register address size and register data size. The addr_size defaults to 8 and the data_size defaults to 16. This can access any arbitrary device on the bus.

Register(far_ship_addr=base, addr_size=asize, data_size=dsize, addr=addr)

Like above, but access a device on the bus master of an ICP-HD or SOC with a bus master.


Attributes

value

RW

The value of the register as an unsigned int with no numerical conversion.
You can write a list of values, and it will do a burst write.

float_value

RW

The value of the register with numerical conversion according to the data type. For example if the data type is fixed8 (8 fraction bits) then 2.0 converts to 0x200.
You can write a list of values, and it will do a burst write.

uncached_value

RO

Do an uncached read, no numerical conversion.

uncached_float_value

RO

Uncached read with numerical conversion.

symbol
name
unique_desc

RW*

The unique symbolic name for the register.

span
addr_span

RO

For a hardware register, how many adjacent registers to span to make one larger logical register.

addr
reg_addr

RO

The address of the register, or offset of the variable.

addr_space

RO

The register page, or variable driver number.

addr_type

RO

The type of register. "REG", "MCU", "SFR", "IND", "FAR1", or "FAR2".

addr_space_id

RW*

The ID of the address space of this register, from the sensor data file. For example 'CORE', 'SYSCTL', etc.

addr_space_name

RW*

The descriptive name of the address space from the sensor data file. For example '0: Core Registers'.

addr_size

RO

The width in bits of the register address.

ship_addr

RO

The base address of the device this register is on.

far_ship_addr

RO

The base address of the device this register is on, if it is accessed though a bus master on the main device or SOC.

mask
bitmask

RW*

The valid bits.

default
default_val

RW*

The default value.

rw

RO

If rw is 0 this indicates the register is read-only. 1 indicates read-write. 2 indicates write-only.

datatype

RW

The data type of the register. See the INI File User's Guide.

minimum

RW

Recommended minimum value, as a floating point number (in other words, after datatype numeric conversion).

maximum

RW

Recommended maximum value, as a floating point number.

bitwidth

RO

The width of the register in bits. For a hardware register, taking into account the span. 8, 16, or 32 bits.

desc
reg_desc
display_name

RW*

The short description from the sensor data or chip data file.

detail

RO

The detailed description from the sensor data or chip data file.

long_desc

RO

Long description from the ldat file.

num_bitfields

RO

How many bitfields are defined for this register.

All bitfields

RW

All bitfields defined for this register in the sensor data or chip data file become attributes of the register. Getting the attribute returns a Bitfield object. To read the bitfield get the value or float_value attribute of the Bitfield.
Setting the attribute constructs a Bitfield object and sets the value or float_value attribute depending on whether the value is a float or not.

*These attributes are only writable if the register is not defined in the parent's sensor data or chip data file.

Methods

bitfield(mask)

Constructs a Bitfield object with this register as the parent and the given bitmask.

bitfield(symbol)

Constructs a Bitfield object with this register as the parent and the given symbolic name.

burst_read(count)

Read count successive registers starting from the address of this register object, normally using a single long I/O operation for best performance. Returns a list object with the result values. Burst read may not be supported for register types that are accessed indirectly.

burst_read_float(count)

Same as burst_read(), but translates the data according the data type of the register and creates a list of floating point values.


Looping Over All Bitfields

The Register object is iterable, and the iteration produces each of the bitfields defined for the parent register. In other words, if rr is a Register object, the following will loop over all bitfields of the register. 

   for b in rr:
        print(' ', b.symbol)



Bitfield Class

The Bitfieldclass represents a subset of the bits in a hardware register, firmware variable, device SFR (memory-mapped register), or any other type of register that is supported by the Register class. 

Constructor

In most cases you would construct a Bitfield object using the bitfield() method or a named bitfield attribute of a Register object.  However, the Bitfield constructor can be called directly

Bitfield(parent, index=i)

Construct a Bitfield object from a parent Register object and an index into the array of defined bitfields for the register.

Bitfield(parent, mask=m)

Construct a Bitfield object from a parent Register object and a bitmask.

Bitfield(parent, symbol=name)

Construct a Bitfield object from a parent Register object and a bitfield symbolic name.


Attributes

value

RW

The value of the bitfield as an unsigned int with no numerical conversion. Writing to a bitfield always uses an uncached read in the read-modify-write cycle.

float_value

RW

The value of the bitfield with numerical conversion according to the data type. Writing to a bitfield always uses an uncached read in the read-modify-write cycle.

uncached_value

RO

Do an uncached read, no numerical conversion.

uncached_float_value

RO

Uncached read with numerical conversion.

parent

RO

The parent Register object.

symbol
name
id

RW*

The symbolic name for the bitfield.

mask
bitmask

RW*

The bitmask of the bitfield.

default

RO

The default value (derived from the default value of the parent).

datatype

RW

The data type of the bitfield. See the INI File User's Guide.

minimum

RW

Recommended minimum value, as a floating point number (in other words, after datatype numeric conversion).

maximum

RW

Recommended maximum value, as a floating point number.

rw

RW*

If 0 then this bitfield is defined as read-only. If 1 then it is read-write. 2 indicates write-only.

desc
display_name

RW*

The short description from the sensor data or chip data file.

detail

RO

The detailed description from the sensor data or chip data file.

long_desc

RO

Long description from the ldat file.

*These attributes are only writable if the bitfield is not defined in the sensor data or chip data file.


Methods

There are no Bitfield methods.

Console Class

The Console class is a file-like class that directs character stream data to the Python Console window. DevWare sets sys.stdin, sys.stdout and sys.stderr to a Console object.

Constructor

Normally you can just use sys.stdin, sys.stdout and sys.stderr to access the Python Console window, but the constructor can be called directly.

Console(unit)

Construct a Console object. If the parameter is 0 the text written will be black (or the default window text color) in the Python Console window. If the parameter is 1 the text will be red and may trigger a pop-up warning dialog (this is used for sys.stderr). The parameter may be omitted and defaults to 0.


Attributes

There are no attributes.

Methods

write(str)

Adds the text to the Python Console output window. This is called implicitly by the Python print() function.

readline(size)

Pops up a small dialog with a text entry control. Returns the text entered by the user. If the size parameter is present and non-negative, the returned string is limited to size characters. This is called implicitly by the Python input() function. If the user cancels the dialog, the return value is an empty string.

flush()

Does nothing. Included for compatibility with other Python file-like objects.

Apbase Methods

getstate(statename)

Returns the value of the specified state variable. Some variables have integer values and some have string values. See the STATE Variables for more details.

setstate(statename, value)

Assign a new value to a state variable. Some state variables are integer valued and some are string valued. The type of the value parameter must match the type of the named state variable. See the STATE Variables  for more details.

image(width, height, type)

Override the calculation of the current sensor output image size and image type. The type parameter is optional. If you only want to set the image type then pass 0 for width and height. See the INI file user’s guide, IMAGE= command for more details. Example:

image(640, 480, ’YCBCR’)

load_preset(preset)

load_preset(file, preset)

Execute an INI file preset. If the file parameter is not given, the method will load from the currently executing ini file, or if that can’t be determined, the main ini file.

multiple_choice(prompt, choices)

Prompt the user with a multiple choice dialog or menu. This is similar to the PROMPT= INI file command. The first parameter should be a prompt string, and the second parameter must be a list. The return value is the user's choice, starting from 1. A zero returned means the user did not make a choice. A -1 means the user clicked a Cancel button. Items in the list that are not strings will be converted to strings with the str() function.

sel = multiple_choice('Choose exposure (ms)', [10, 20, 50, 100, 'Maximum'])

noise_results()

Get the most recent Noise Measurement Results, as a dictionary.

noise = apbase.noise_results()
print('T1_Y_RMS_Dyn', noise['T1_Y_RMS_Dyn'])

log(string)

Adds a string to the application’s log.

delay(ms)

Delay for the specified number of milliseconds.

open_iolog(flags, file)Open a new IO log file with the given flags. See the MI_LOG symbol definitions in midlib2.h. The file name is optional.
close_iolog()Stop all logging.
iolog_filename()Returns the current IO log file name.
iolog_flags()Returns the current IO log flags.
iolog_set_flags(flags)Change the logging flags.
iolog_msg(message)Add a message to the log if MI_LOG flag is set.
iolog_debug_message(text=message, source=sourcefile, func=functionname, line=linenumber)Add a message to the log if MI_LOG_DEBUG flag is set. You can optionally include your source code file name, function name and line number.


Apbase Constants

home

The Aptina Imaging installation directory.

num_cameras

How many cameras were detected.

All mi_error_code

All apbase API mi_error_code contants. Example: apbase.MI_CAMERA_SUCCESS.

All mi_product_ids

All apbase API mi_product_ids constants. Example: apbase.MI_DEMO2.

All mi_reg_accessibility

All apbase API mi_reg_accessibility constants. Example: apbase. MI_RW_READONLY.

All mi_rx_types

All apbase API mi_ rx_types constants. Example: apbase.MI_RX_HISPI.

All mi_rx_modes

All apbase API mi_rx_modes constants. Example: apbase.MI_RX_HISPI_S.


DevWare Module Reference

The devware module provides other DevWare application functions not directly related to accessing the camera.

DevWare Methods

The devware module methods are based on the methods exposed through DevWare's COM interface
For more details about DevWare state variables see the INI file document

getstate(statename)

Returns the value of the specified state variable. Some variables have integer values and some have string values. See the INI file user's guide for more details.

setstate(statename, value)

Assign a new value to a state variable. Some state variables are integer valued and some are string valued. The type of the value parameter must match the type of the named state variable.

getoption(optionname)

Returns the value of an integer-valued option variable. See the COM interface document for more details.

setoption(optionname, value)

Assign a new value to an option variables. Option values are persistent across invocations of DevWare.

getoption_str(optionname)

Like getoption() but for string values.

setoption_str(optionname, value)

Like setoption() but for string values. Option values are persistent across invocations of DevWare.

get_mouse_selection()

Returns the Mouse Selection on the DevWare left-hand Info panel and the currently selected image area. Returns a tuple with five items; the selection type, the x and y coordintates of the start of the area, and the x and y coordinates of the end of the area. Example:
sel, x1, y1, x2, y2 = get_mouse_selection()
Sel can be 'off', 'row', 'column', 'rectangle', or 'point'. It can also be an index from 0 to 4, relative to the listed names.

For 'row' only y1 is relevant, for 'column' only x1 is relevant, and for 'point' only x1 and y1 are relevant.

set_mouse_selection(sel, x1, y1, x2, y2[, subimage=<value>])

Set a new selection area.

See "get_mouse_selection()" for parameter values.

get_active_mouse_sel()Get the index of the current active Mouse Selection. Returns an INT, from 0 to 7.
set_active_mouse_sel(sel)Set the index of the current active Mouse Selection. "sel" is a value from 0 to 7.

image(width, height, type)

Override DevWare's calculation of the current sensor output image size and image type. The type parameter is optional. If you only want to set the image type then pass 0 for width and height. See the INI file user's guide, IMAGE= command for more details. Example:
image(640, 480, 'YCBCR')

load_preset(preset)
load_preset(file, preset)

Execute an INI file preset. If the file parameter is not given, the method will load from the currently executing ini file, or if that can't be determined, the main ini file.

open_ini_file(file)

Create a new Additional Presets dialog showing the given file. If the file parameter is omitted or an empty string then DevWare puts up a standard Open File browse dialog and the user may choose the file.

rebuild_user_toolbars()Re-build the User Toolbars from the ini files (in case the files changed).
update_user_toolbars()Update checked/enabled states of User Toolbars.

upload_firmware(file, burst)

Loads firmware or firmware patches from a file. The burst parameter determines whether to use I2C burst writes. Returns the actual number of bytes loaded.
See the COM interface document for more details.

upload_image_file(file, offset, length)

Loads a test image (or any binary data) to a supported emulator platform. The offset and length parameters are optional. Same as the COM interface function.

command(cmd, param)

The command() method sends a WM_COMMAND message to the DevWare main window. See the COM interface document for more details.

getstate(state)Get the value of a ColorPipe state variable. See the ColorPipe User Guide for details.
setstate(state)Set the value of a ColorPipe state variable. See the ColorPipe User Guide for details.

stop(bool)

Stops or starts the image capture and image display threads in DevWare. Call stop(True) to stop the threads, and stop(False) to resume them. Every call to stop(True) must be matched with a call to stop(False). DevWare stops the threads before executing an ini file preset, so this function will have no effect in that situation. But if your Python code may run in a thread you created, or may be called from a plug-in or from the COM interface then the capture and display threads may be running concurrently with your Python code.

begin_access_regs()

Tells DevWare that register accesses are following. If the device driver can't do simultaneous register access and frame capture then this function will pause the image capture thread. Using this function is not necessary, but calling begin_access_regs() before a sequence of many register accesses saves the overhead of pausing and unpausing the capture thread on each register access. This function is typically not needed in ini file presets because the capture thread is normally already turned off before the ini preset is executed. Every call to this function must be matched with a call to end_access_regs() or else the capture thread will not resume.

end_access_regs()

Resume the image capture thread if it was paused by a call to begin_access_regs().

log(string)

If the Register Log window is enabled, adds a string to the log.

get_warning_choice(id)

Get the automatic response to the DevWare warning dialog given by the id number. The response can be devware.IDOK for OK or Yes, devware.IDNO for No, or -1 to show the warning dialog.

set_warning_choice(id, choice)

Set the automatic response to the DevWare warning dialog.

reset_warnings()

Reset all warning dialogs to be shown (no automatic response).

suppress_warnings()Suppress all warning dialogs.

close()

Equivalent to clicking the close button on the DevWare main window. This is may be preferred to sys.exit(), which may cause an error message pop-up dialog. The function allows a parameter, but ignores it. Note that this function does return, and if executed in the DevWare main UI thread, DevWare doesn't exit until the script is finished.

add_check_box(params)Add scriptable checkbox. See  Command Syntax, below, for params format.
add_spin_box(params)Add scriptable spin box. See  Command Syntax, below, for params format.
add_float_spin_box(params)Add scriptable float spin box. See  Command Syntax, below, for params format.
add_float_slider(params)Add scriptable float slider control. See  Command Syntax, below, for params format.
add_list_box(params)Add list box with enumeration. See  Command Syntax, below, for params format.
add_edit_box(params)Add edit string box. See Command Syntax, below, for params format.
refresh_control(tab, group, label)Refresh the targeted control. Parameters are those supplied in one of the Command Syntax calls.
get_refresh_interval()Get the refresh interval in milliseconds. Returns an INT.
set_refresh_interval(value)Change the refresh interval in milliseconds.
getOpenFileName(params)Get filename from pop-up file dialog. params are strings of title, directory, and filter; do a Web search of "QFileDialog::getOpenFileName" for details.
getSaveFileName(params)Get filename from pop-up file dialog. params are strings of title, directory, and filter; do a Web search of "QFileDialog::getSaveFileName" for details.
showMessageBox(params)

Pop-up a messagebox. params are title, message, and button.
For title and message, provide strings.
For button provide an INI of; 0 for "OK", 1 for "OK", "Cancel", 2 for "Retry", "Ignore", "Abort", 3 for "Yes", "No", "Cancel".
Returns an INT of; 1 = OK, 2 = Cancel, 3 = Abort, 4 = Retry, 5 = Ignore, 6 = Yes, 7 = No

graph_gettype()Get the current Analysis Graph type. 0 = Intensity; 1 = Histogram; 2 = Cumulative Intensity; 3 = Cumulative Histogram; 4 = Noise; 5 = Vectorscope; 6 = Embedded Statistics; 7 = SOC Statistics
graph_settype()Set the Analysis Graph type.
graph_getcolortype(type)Get current Analysis Graph color type; 0 to 2 = RGB, Bayer/YCbCr, HSV, FFT.
graph_setcolortype(type)Set Analysis Graph color type; 0 to 2 = RGB, Bayer/YCbCr, HSV, FFT.
graph_getdata()Get the data from the current Analysis Graph.
histogram_getmode()Get the current histogram mode. 0 = RGB; 1 = Luminance.
histogram_setmode()Set the histogram mode.
histogram_mean()If Analysis Graph is set to Histogram (1 or 3) and the histogram mode is Luminance (1) this returns the current mean of the data.
histogram_median()If Analysis Graph is set to Histogram (1 or 3) and the histogram mode is Luminance (1) this returns the current median of the data.
histogram_max()If Analysis Graph is set to Histogram (1 or 3) and the histogram mode is Luminance (1) this returns the current maximum of the data.
histogram_stddev()If Analysis Graph is set to Histogram (1 or 3) and the histogram mode is Luminance (1) this returns the current standard deviation of the data.

Custom Register Dialog Definition via "Register Tabs" preset

The pre-defined INI preset "Register Tabs" is used to define a customized version of the Register Dialog.
It uses contructs from Python to define and control the entries connected to registers or Python "getter" and "setter" routines.

The types of controls include;

  • Check Box; enable/disable.

  • Spin Box; up/down arrows to run through values. Also allows for direct entry of a value.

  • Slider; a slider to run through values.

  • List Box; a user-defined set of values to select from.

Start by creating an INI preset named "[Register Tabs]". Populate it with "LOAD=Python:<Python presets>".
Then populate the individual <Python presets> accordingly to define the tabs, groups, and controls to be created.

You can add this preset to the main product INI, or as a separate INI file; in either case, you load the controls by running the Register Tabs preset.
Once you do that, you can access the Custom Register Dialog via the "Register" menu item pull-down, labeled "Show Script Interface".

Note: The Custom Register Dialog (aka "Script Interface") is mutually exclusive from the default Register Interface.

Command Syntax

Note: [ ] items are optional.

The required parameters for commands;

<tab>; string: tab name, and the tab in which the object will be placed.
<group>; string: group heading name, and the group in which the object will be placed.
<label>; string: object display name.
<register>; Python object: the name of the register to be referenced.
   In formats supported by the "reg." implementation.
   Note: this parameter can be substitued with a pair of standard Python "getter" and "setter" routines.
<combo>; Python object: an array of string/integer pairs for the display name and associated value.

The optional parameters for commands;
<enable>; Python object: bool - true to enable, false to disable (but the control still appears).
   If not supplied, defaults to true.
<refreshcount>; integer: number of times to refresh the value - 0 for none.
   If not supplied, defaults to 1.
<tooltip>; string: the ToolTip to associate with the control.
   If not supplied, the value from the Data Sheet is used if available.
<min>; integer: minimum value to be used.
   If not supplied, defaults to 0.
<max>; integer: maximum value to be used.
   If not supplied, defaults to the register's mask size (8/16/32 bits).
<step>; integer:  increase/decrease of each movement of the object control (spin_box or slider). 
<decimals>; integer: number of significant digits for double/float parameters.

add_check_box(<tab>, <group>, <label>, <register>[, <enable>, <refreshcount>, <tooltip>])

Create a check box to set a register or bitfield to true (1) or false (0).

Examples:
devware.add_check_box("Common", "Targets", "Gain Target", reg.PANORAMA.ENABLE)
devware.add_check_box("Common", "Targets", "Gain Target", reg.PANORAMA.ENABLE, True, 1, "Enable/Disable Panorama")

Create a check box to set the info dialog show on/off, replacing <registers> with a pair of python getter and setter routines.

Example:

def getInfo():

    return devware.getoption('InfoDlg Show')  

def setInfo(s):    

    devware.setoption('InfoDlg Show',s)

devware.add_check_box(tab='Common', group='Options', label='Info Dialog Show', getter=getInfo, setter=setInfo)

add_spin_box(<tab>, <group>, <label>, <register>[, <enable>, <refreshcount>, <min>, <max>, <step>, <tooltip>])

Create a spin box to set a register or bitfield from min to max, by step.

Example:
devware.add_spin_box("Common", "Targets", "Gain Target", reg.CAM_AET_TARGET_GAIN)
devware.add_spin_box("Common", "Targets", "Gain Target", reg.CAM_AET_TARGET_GAIN, True, 1, 0x40, 0xFF, 10, "Set Target Gain")


Create a spin box to set the number of capture images, replacing <registers> with a pair of python getter and setter routines.

Example:
def getimages():
    return apbase.getstate('Num Capture Frames')

def setimages(i):

    apbase.setstate('Num Capture Frames',i)

devware.add_spin_box("Common", "Options", "Nuuber of captured images", getimages, setimages, min=1, max=100)


add_float_spin_box(<tab>, <group>, <label>, <register>[, <enable>, <refreshcount>, <min>, <max>, <step>, <tooltip>])

Create a spin box to set a register or bitfield from min to max, by step.

Example:
devware.add_float_spin_box("Common", "Targets", "Gain Target", reg.CAM_SFX_SEPIA_CR)
devware.add_float_spin_box("Common", "Targets", "Gain Target", reg.CAM_SFX_SEPIA_CR, True, 1, 1.22, 6.545, .5, "Set Effect SEPIA Red")
Note: <min>, <max>, and <step> are all double/float format.

add_slider(<tab>, <group>, <label>, <register>[, <enable>, <refreshcount>, <min>, <max>, <step>, <tooltip>])

Create a slider to set a register or bitfield from min to max, by step.

Example:
devware.add_slider("Common", "Targets", "Gain Target", reg.CAM_AET_TARGET_GAIN)
devware.add_slider("Common", "Targets", "Gain Target", reg.CAM_AET_TARGET_GAIN, True, 1, 0x40, 0xFF, 10, "Set Target Gain")

Create a slider to set the AE Target, replacing <registers> with a pair of python getter and setter routines.

Example:

def get_aetarget():

    return apbase.getstate('Auto Exposure Target')

def set_aetarget(t):

    apbase.setstate('Auto Exposure Target',t)

devware.add_slider("Common", "Targets", "AE Target", get_aetarget, set_aetarget, min=1, max=100)


add_float_slider(<tab>, <group>, <label>, <register>[, <enable>, <refreshcount>, <min>, <max>, <step>, <tooltip>])

Create a slider to set a register or bitfield from min to max, by step.

Example:
devware.add_float_slider("Common", "Targets", "Gain Target", reg.CAM_SFX_SEPIA_CR)
devware.add_float_slider("Common", "Targets", "Gain Target", reg.CAM_SFX_SEPIA_CR, True, 1, 0x40, 0xFF, 10, "Set Effect SEPIA Red")

add_list_box(<tab>, <group>, <label>, <register>, <combo>[, <enable>, <refreshcount>, <tooltip>])

Create a list box with the given name/value pairs.

Example:
orientation = [ ("Normal",           0),
                       ("Horizontal flip",    1),
                       ("Vertical flip",      2),
                       ("Hor. & Vert. flip",   3)]
devware.add_list_box('Common', 'Context', 'Orientation', reg.ORIENTATION, orientation)
devware.add_list_box('Common', 'Context', 'Orientation', reg.ORIENTATION, orientation, True, 1, "Set Orientation")


Create a list box with the given name/string value, to set the capture file name with predefined sensor ID,

replace the <register> with a pair of getter and setter routines.

Example:

sensorID_list = [("SOC380",'SOC380'),

                         ("SOC3140",'SOC3140'),

                         ("SOC5140", 'SOC5140')]

def getsensorID():

    return sensorID

def setsensorID(s):

    sensorID = s  

    savedir = devware.getoption_str('Capture File')

    savedir = os.path.dirname(savedir)

    savename = os.path.join(savedir, sensorID)

    devware.setoption_str('Capture File', savename)

devware.add_list_box('Common', 'Options', 'Save File Name',  getsensorID,  setsensorID,  sensorID_list)