IVC-100-120-200G GPIO Module support

Anything you want added or changed in future versions of ZoneMinder? Post here and there's a chance it will get in! Search to make sure it hasn't already been requested.
Post Reply
vulpes210
Posts: 2
Joined: Fri May 04, 2007 4:07 pm
Location: Johannesburg

IVC-100-120-200G GPIO Module support

Post by vulpes210 »

Hi,

I've been using an IVC-200 from IEI with Zoneminder for some time and I've had very good experiences with it.

IEI also sells the same card with an integrated GPIO Module on it. So I bought on of those cards because a SDK for Linux was provided with the card, and the same setup would provide support for the IVC-100G and the IVC_120G as well.

The idea was to integrate an access control system with Zonemider and if Zoneminder raised an alarm via the GPIO module, access would be prevented.

However to my greatest disappointment I didn't manage to get that to work, and after weeks of googling on the internet I'm not even a step closer to a solution.

The problem is: How do I get Zoneminder to talk to the GPIO module.

Provided with the SDK are two files, a howto and a header file named sdk-howto and ieibt878.h.

The contents of the howto:
First of all, you must include the header file ieibt878.h in your application.

1. To use auto-detect function (detect signal removal automatically), use structure iei_auto_detect and VIDIOC_IEI_SET_AUTO_DETECT ioctl call. The rules are shown as below:

To enable auto-detect function, assign auto_detect to 1
To disable auto-detect function, assign auto_detect to 0

To get auto-detect function statue, use structure iei_auto_detect and VIDIOC_IEI_GET_AUTO_DETECT ioctl call.

2. To use auto-switch function (switch between channels automatically), use structure iei_auto_switch and VIDIOC_IEI_SET_AUTO_SWITCH ioctl call. The rules are shown as below:

To enable auto-switch function, assign auto_switch to 1
To disable auto-switch function, assign auto_switch to 0

To get auto-switch function statue, use structure iei_auto_switch and VIDIOC_IEI_GET_AUTO_SWITCH ioctl call.

3. To set channels, use structure iei_channel_mask and VIDIOC_IEI_SET_CHANNEL_MASK ioctl call. The rules are shown as below:

To enable/disable channel 1, assign bit 0 of ch_mask to 1/0
To enable/disable channel 2, assign bit 1 of ch_mask to 1/0
To enable/disable channel 3, assign bit 2 of ch_mask to 1/0
To enable/disable channel 4, assign bit 3 of ch_mask to 1/0

For example, if you want to enable channel 1 and 3 disable channel 2 and 4, you should assign ch_mask to 0x5.

To get channel status, use structure iei_channel_mask and VIDIOC_IEI_GET_CHANNEL_MASK ioctl call.

4. To set GPIO outputs, use structure iei_gpio and VIDIOC_IEI_SET_GPIO ioctl call. The rules are shown as below:

To set the output 1, assign bit 0 of gpio_target to 1 and bit 0 of gpio_value to 0 or 1
To set the output 2, assign bit 1 of gpio_target to 1 and bit 1 of gpio_value to 0 or 1
To set the output 3, assign bit 2 of gpio_target to 1 and bit 2 of gpio_value to 0 or 1
To set the output 4, assign bit 3 of gpio_target to 1 and bit 3 of gpio_value to 0 or 1

For example, if you want to set the output 1 and 3 to 0 and set the output 2 and 4 to 1, you should assign gpio_target to 0xf and gpio_value to 0xa.

To get GPIO inputs and outputs, use structure iei_gpio and VIDIOC_IEI_GET_GPIO ioctl call. The meaning of the returned value is shown as below:

gpio_target - don't care
gpio_value - bit 0 = input1, bit 1 = input 2, bit 2 = input 3, bit 3 = input 4, bit 4 = output 1, bit 5 = output 2, bit 6 = input 1, bit 7 = output 4
The content of the header file ieibt878.h

Code: Select all

#ifndef _IEIBT878_H
#define _IEIBT878_H

struct iei_auto_switch
{
	int		auto_switch;
};

struct iei_channel_mask
{
	int		ch_mask;
};

struct iei_auto_detect
{
	int		auto_detect;
};

struct iei_gpio
{
	int		gpio_target;
	int		gpio_value;
};

struct iei_card_id
{
	unsigned long	dwSubsystemId;
	unsigned long	dwSubsystemVendorId;
};

struct iei_signal_status
{
	int		signal_status;
};

struct iei_norm_status
{
	int		is_525_scanline;
};

#define VIDIOC_IEI_SET_AUTO_SWITCH	_IOW('v', 200, struct iei_auto_switch)
#define VIDIOC_IEI_GET_AUTO_SWITCH	_IOR('v', 201, struct iei_auto_switch)
#define VIDIOC_IEI_SET_CHANNEL_MASK	_IOW('v', 202, struct iei_channel_mask)
#define VIDIOC_IEI_GET_CHANNEL_MASK	_IOR('v', 203, struct iei_channel_mask)
#define VIDIOC_IEI_SET_GPIO		_IOW('v', 204, struct iei_gpio)
#define VIDIOC_IEI_GET_GPIO		_IOR('v', 205, struct iei_gpio)
#define VIDIOC_IEI_GET_CARD_ID		_IOR('v', 206, struct iei_card_id)
#define VIDIOC_IEI_GET_SIGNAL_STATUS	_IOR('v', 207, struct iei_signal_status)
#define VIDIOC_IEI_SET_AUTO_DETECT	_IOW('v', 208, struct iei_auto_detect)
#define VIDIOC_IEI_GET_AUTO_DETECT	_IOR('v', 209, struct iei_auto_detect)
#define VIDIOC_IEI_GET_NORM_STATUS	_IOR('v', 210, struct iei_norm_status)

#define	ETIMEOUT	500	/* RISC command time-out */

#endif
Any advise or help would be greatly appreciated.
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

The SDK appears to define ioctls that can address the GPIO functions on the card. This isn't something that is directly supported by ZM as there is no standard but you may still be able to get it to work. I think your best bet would be to write a simple c/c++ program to control these ioctls and then integrate that via zmtrigger.pl.

The integrate is relatively simple but your first task is to create something that can use the ioctls and which you can test standalone. The function ioctl calls are nothing special in themselves, only the parameters are specific to your card so you should be able to find plenty sample code, including in zm_local_camera.cpp
Phil
Post Reply