Transport DLL Development Guide
Introduction
A transport is the link between a camera device and the onsemi software libraries. The purpose of a transport is to implement the camera control (read and write registers, set modes) and image acquisition functions needed by the higher level software. With a Transport DLL you can:
Support an onsemi sensor on a device other than the Demo System camera so DevWare or any other ApBase-based application will work with the device.
Create a software simulated camera and sensor, simulating either an existing sensor or new sensor, and be able to use DevWare as the user interface for the simulation.
Transport DLL Exports
The functions you need to implement and export from your Transport DLL are described below.
The exported functions should use the C calling convention. If you are using C or C++ this would normally be the default, so no special syntax is needed. If it is not, the keyword to force a function to the C calling convention is normally __cdecl in most C/C++ compilers. The function prototypes in this document assume C calling convention is the default.
To make your functions export from the DLL in C or C++ you would normally precede the function declaration with __declspec(dllexport).
The symbols and data structures used by the Transport DLL interface are defined in the midlib2.h and midlib2_trans.h header files.
Several of these functions are required to be implemented and exported from your DLL. If they are not exported then the onsemi libraries will not load the DLL. The remaining functions are optional. If an optional function is not present then either a default handler will be provided to the application, of the feature will not be available. Whether a function is required or optional will be noted for each one below.
DLL Export SetHelpersDLL()
Definition:
__declspec(dllexport) mi_s32 SetHelpersDLL(mi_transport_helpers_t *pHelpers);
Summary:
This function is called when the DLL is loaded, before any other function. The parameter provides pointers to some functions that may be useful to a Transport DLL, but are not appropriate to be called by ordinary applications, so are not exported from the libraries like the main APIs.
Parameters:
pHelpers | Pointer to a structure containing pointers to helper functions. |
Returns:
MI_CAMERA_SUCCESS | Initialization successful. |
Optional:
This function is not necessary if you don't need the helper functions.
The following sections describe the helper functions in the pHelpers structure.
Helper Function getSensor()
Definition:
mi_s32 getSensor(mi_camera_t *pCamera, const char *dir_or_file);
Summary:
Performs the device probe to automatically find the correct sensor data file for the current sensor, and create the pCamera->sensor structure from the data in the file. Pass in the pCamera pointer and the name of a file or directory. If the parameter is a sensor data file, the function will load the file. If the parameter is a directory, the function will search the directory for a sensor data file that matches the device and load it.
Parameters:
pCamera | Pointer to a camera structure. |
dir_or_file | Name of a directory or sensor data file. |
Returns:
MI_CAMERA_SUCCESS | Initialization successful. |
MI_SENSOR_FILE_PARSE_ERROR | A syntax error was found in the sensor data file. |
MI_SENSOR_DOES_NOT_MATCH | No sensor data file was found that matches the current sensor. |
MI_CAMERA_ERROR | Various other error conditions. |
Helper Function updateFrameSize()
Definition:
void updateFrameSize(mi_camera_t* pCamera , mi_u32 nWidth, mi_u32 nHeight, mi_s32 nBitsPerClock, mi_s32 nClocksPerPixel);
Summary:
Boilerplate code for UpdateFrameSizeDLL(). Sets pCamera->sensor->width, >height, ->pixelBits, and ->pixelBytes according to the parameters. Also sets BITS_PER_CLOCK and CLOCKS_PER_PIXEL in the camera context structure (see setContext() below). Sets pCamera>sensor->bufferSize to width * height * pixelBytes; you may need to fix up the bufferSize after calling this function. Call from UpdateFrameSizeDLL(). See sample code.
Parameters (same as UpdateFrameSizeDLL()):
pCamera | Pointer to a camera structure. |
nWidth | New image width, or 0 to keep the current width. |
nHeight | New image height, or 0 to keep the current height. |
nBitsPerClock | New bits/pixel clock, or 0 to keep the current value. |
nClocksPerPixel | New clocks/pixel, or 0 to keep the same value. |
Returns:
void |
Helper Function updateImageType()
Definition:
void updateImageType(mi_camera_t* pCamera);
Summary:
Make sure the sensor->imageType field is consistent with the current bits per pixel. Call from UpdateFrameSizeDLL() before returning. See sample code.
Parameters:
pCamera | Pointer to a camera structure. |
Returns:
void |
Helper Function errorLog()
Definition:
mi_s32 errorLog(mi_s32 errorCode, mi_s32 errorLevel, const char *logMsg, const char *szSource, const char *szFunc, mi_u32 nLine);
Summary:
Adds an error message to the log file. This is the error logging that is controlled on the DevWare Options dialog. Normally you call this function from the return statement. For example, instead of:
return MI_CAMERA_ERROR;
Use
return HelperFn->errorLog(MI_CAMERA_ERROR, -1, "Couldn't open driver",
_FILE, __FUNCTION, __LINE_);
Since the last three parameters are always the same, you can save typing by creating a preprocessor macro.
#define ERRORLOG(e,m) HelperFn->errorLog(e,-1,m,_FILE,FUNCTION,LINE_)
The example becomes:
return ERRORLOG(MI_CAMERA_ERROR, "Couldn't open driver");
Parameters:
errorCode | An error code defined in midlib2.h. |
errorLevel | Severity of the error. Normally you can use -1 for this parameter as the severity is implied by the error code. |
logMsg | Additional information to put in the log file. |
szSource | Source code file name where error occurred. Normally _FILE_. |
szFunc | Name of function where error occurred. Normally _FUNCTION_ or "?" if your compiler doesn't support that symbol. |
nLine | Source code line number where error occurred. Normally _LINE_. |
Returns:
errorcode | Always returns the first parameter. |
Helper Function log()
Definition:
void log(mi_s32 logType, const char *logMsg, const char *szSource, const char *szFunc, mi_u32 nLine);
Summary:
Adds a message to the log file. This is the logging that is controlled on the DevWare Options dialog. As with errorLog(), you can save typing by creating a macro that fills in the last three parameters automatically. Note that this function has no equivalent to the errorLevel parameter of errorLog().
Parameters:
logType | A log message type defined in midlib2.h. The different log types can be turned on/off by the user on the DevWare Options dialog. |
logMsg | The text of the message. |
szSource | Source code file name where this log() call is located. Normally _FILE_. |
szFunc | Name of function where this log() call is located. Normally _FUNCTION_. |
nLine | Source code line number of this log() call. Normally _LINE_. |
Returns:
void |
Helper Function setMode()
Definition:
mi_s32 setMode(mi_camera_t *pCamera, mi_modes mode, mi_u32 val);
Summary:
This is the default setMode() handler. If you are implementing SetModeDLL() you should call this function from your SetModeDLL() so the pCamera structure stays consistent. If you don't implement SetModeDLL() in your DLL then the software automatically uses this function instead. See SetModeDLL().
Parameters:
pCamera | Pointer to the camera structure. |
mode | The mode to set. |
val | The new mode value. |
Returns:
MI_CAMERA_SUCCESS | Function was successful. |
MI_CAMERA_ERROR | An error occurred. |
Helper Function getMode()
Definition:
mi_s32 getMode(mi_camera_t *pCamera, mi_modes mode, mi_u32 *val);
Summary:
Calls the default getMode() handler. If you are implementing GetModeDLL() you can call this function to handle modes that you don't need to override. If you don't implement GetModeDLL() in your DLL then the software automatically uses this function instead. See GetModeDLL().
Parameters:
pCamera | Pointer to the camera structure. |
mode | The mode to get. |
val | Pointer to a 32-bit variable to store the mode value. |
Returns:
MI_CAMERA_SUCCESS | Function was successful. |
MI_CAMERA_ERROR | An error occurred. |
Helper Function setContext()
Definition:
mi_s32 setContext(mi_camera_t *pCamera, mi_context_fields field, mi_intptr val);
Summary:
Set fields in the pCamera->context structure. The context structure holds internal data associated with the camera. The context structure definition can change frequently and is not published. This function gives access to the fields needed by a Transport DLL. See the sample code.
MI_CONTEXT_PRIVATE_DATA gives you a convenient way to associate your own data with the pCamera. The val parameter can be an integer or a pointer to a data structure.
If the field is MI_CONTEXT_DRIVER_INFO, the val parameter is interpreted as a const char *. The DRIVER_INFO is a string up to 255 characters long that will be included in bug reports, and can be viewed by the user in DevWare with the menu Help System Dump. You can put any information you want that you think would be useful.
Parameters:
pCamera | Pointer to the camera structure. |
Field | The field to set. |
Val | The new field value. |
Returns:
MI_CAMERA_SUCCESS | Function was successful. |
MI_CAMERA_ERROR | An error occurred. |
Field MI_CONTEXT_PRIVATE_DATA
Summary:
MI_CONTEXT_PRIVATE_DATA gives you a convenient way to associate your own per-camera device data with the pCamera pointer. The val parameter can be an integer or a pointer to a data structure.
Field MI_CONTEXT_DRIVER_INFO
Summary:
In this case the val parameter is interpreted as a const char *. The DRIVER_INFO is a string up to 255 characters long that will be included in bug reports, and can be viewed by the user in DevWare with the menu Help System Dump. You can put any information you want that you think would be useful.
Field MI_CONTEXT_BITS_PER_CLOCK
Summary:
Initialize the bits per clock value. Combined with the clocks per pixel, this defines the format of pixels.
Field MI_CONTEXT_CLOCKS_PER_PIXEL
Summary:
Initialize the clocks per pixel value. Combined with the bits per clock, this defines the format of pixels.
Field MI_CONTEXT_PIXCLK_POLARITY
Summary:
Initialize the pixel clock polarity for parallel data.
Helper Function getContext()
Definition:
mi_s32 getContext(mi_camera_t *pCamera, mi_context_fields field, mi_intptr *val);
Summary:
Get fields from the pCamera->context structure. See the sample code. If the field is MI_CONTEXT_DRIVER_INFO, the val parameter is interpreted as a char *, and the buffer needs to be at least 256 bytes.
Parameters:
pCamera | Pointer to the camera structure. |
field | The field to get. |
val | Pointer to a variable to hold the field value. |
Returns:
MI_CAMERA_SUCCESS | Function was successful. |
MI_CAMERA_ERROR | An error occurred. |
Helper Function unswizzleBuffer()
Definition:
void unswizzleBuffer(mi_camera_t *pCamera, mi_u8 *pInBuffer);
Summary:
Unswizzles the data in the buffer. Call from your GrabFrameDLL() function as needed to unswizzle Bayer data. Unswizzling refers to putting out-of-order bits into the correct order. For example, 10-bit unswizzling does the following:
x x x x x x 1 0 9 8 7 6 5 4 3 2 x x x x x x 9 8 7 6 5 4 3 2 1 0
Parameters:
pCamera | Pointer to the camera structure. |
pInBuffer | Pointer to the raw data |
Returns:
void |
Helper Function readReg()
Definition:
mi_u32 readReg(mi_camera_t *pCamera, const char *szRegister, const char *szBitfield, mi_s32 bCached);
Summary:
Reads a named sensor register or register bitfield, optionally using the cached value kept by the library. If the szBitfield parameter is NULL or "" it reads the whole register. This function doesn't report errors, just returns 0 if an error occurs. Indirectly calls one of the register read functions, if needed.
Parameters:
pCamera | Pointer to the camera structure. |
szRegister | Name of a sensor register defined in the sensor data file. |
szBitfield | Name of a bitfield of the register or NULL. |
bCached | If non-zero then get the register value from the cache instead of reading the hardware. |
Returns:
Register or bitfield value |
Helper Function getBoardConfig()
Definition:
mi_s32 getBoardConfig(mi_camera_t *pCamera, const char *dir_or_file);
Summary:
If the camera is an onsemi Demo camera such as Demo2X or Demo3, this function fills in the chip[] array of the pCamera structure by loading .cdat files that correspond to FPGAs or peripherals on the camera system I2C bus.
Parameters:
pCamera | Pointer to a camera structure. |
dir_or_file | Path to sensor data file (same as used for getSensor()). |
Returns:
MI_CAMERA_SUCCESS | Initialization successful (even if no matching cdat files were found). |
MI_PARSE_FILE_ERROR | Error opening the config file. |
Helper Function freeBoardConfig()
Definition:
mi_s32 getBoardConfig(mi_camera_t *pCamera);
Summary:
Clean up after getBoardConfig(); removes all items in chip[] array of the pCamera structure.
Parameters:
void |
Returns:
MI_CAMERA_SUCCESS | Initialization successful (even if no matching cdat files were found). |
DLL Export OpenCameraDLL()
Definition:
__declspec(dllexport) mi_s32 OpenCameraDLL(mi_camera_t *pCamera, const char *sensor_dir_file, int deviceIndex);
Summary:
This function is called when the DLL is loaded, repeatedly, once for each camera. The deviceIndex parameter will = 0 on the first call, 1 on the second call, and so on. For each camera, do any internal initialization you may need. Fill in pCamera fields including pCamera->sensor, but do not touch pCamera->context, which is already initialized and is used internally by the onsemi libraries. You can use the setContext() helper function to associate the deviceIndex and/or any other private per-camera data to the pCamera object. The sensor_dir_file parameter is the name of the sensor data file or directory passed by the application to ap_DeviceProbe(). You can quickly initialize your pCamera->sensor with the helper function getSensor().
If all cameras have already been initialized, return MI_CAMERA_ERROR to end the init process. For example, if there are two cameras, return MI_CAMERA_SUCCESS on deviceIndex = 0 and deviceIndex = 1, and return MI_CAMERA_ERROR on deviceIndex = 2.
Parameters:
pCamera | Pointer to the camera structure. |
sensor_dir_file | Name of sensor data file or directory to search for sensor data files. |
Returns:
MI_CAMERA_SUCCESS | Initialization successful. |
Other error code | In case of an error, or when all cameras have been initialized. If this is deviceIndex = 0 then the error code will be passed back to the application. |
Required:
If this function is not exported, the Transport DLL will be ignored.
DLL Export CloseCameraDLL()
Definition:
__declspec(dllexport) mi_s32 CloseCameraDLL(mi_camera_t *pCamera);
Summary:
This is the last function called before the DLL is unloaded. Free all memory and resources. Do not free pCamera or pCamera->context. You may, but do not need to, free pCamera->sensor.
Parameters:
pCamera | Pointer to the camera structure. |
Returns:
The return value is ignored.
Required:
If this function is not exported, it could cause memory leaks.
DLL Export StartTransportDLL()
Definition:
__declspec(dllexport) mi_s32 StartTransportDLL(mi_camera_t *pCamera);
Summary:
Implements the mi_camera_t::startTransport() function. This function will be called before grabFrame(), readSensorRegister(), etc. Get ready to do I/O functions on the camera. Open the device driver, etc.
Parameters:
pCamera | Pointer to the camera structure. |
Returns:
MI_CAMERA_SUCCESS | Function was successful. |
Other error code | Appropriate for the error that occurred. |
Required:
If this function is not exported, the DLL will be ignored.
DLL Export StopTransportDLL()
Definition:
__declspec(dllexport) mi_s32 StopTransportDLL(mi_camera_t *pCamera); Summary:Implements the mi_camera_t::stopTransport() function. The application will not do any more I/O to the device. Close driver, etc. Usually this is called right before closeCamera(). Parameters: