Skip to content

Commit 95f2511

Browse files
committed
Adding the extension code
1 parent 3df64c3 commit 95f2511

File tree

5 files changed

+309
-0
lines changed

5 files changed

+309
-0
lines changed

config.m4

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
PHP_ARG_WITH(ftdi, whether to enable ftdi support,
2+
[ --with-ftdi[=DIR] Enable ftdi support. DIR is the prefix to libftdi installation directory.], yes)
3+
4+
if test "$PHP_FTDI" != "no"; then
5+
6+
7+
dnl Get PHP version depending on shared/static build
8+
9+
AC_MSG_CHECKING([PHP version is at least 5.2.0])
10+
11+
if test -z "${PHP_VERSION_ID}"; then
12+
if test -z "${PHP_CONFIG}"; then
13+
AC_MSG_ERROR([php-config not found])
14+
fi
15+
PHP_FTDI_FOUND_VERNUM=`${PHP_CONFIG} --vernum`;
16+
PHP_FTDI_FOUND_VERSION=`${PHP_CONFIG} --version`
17+
else
18+
PHP_FTDI_FOUND_VERNUM="${PHP_VERSION_ID}"
19+
PHP_FTDI_FOUND_VERSION="${PHP_VERSION}"
20+
fi
21+
22+
if test "$PHP_FTDI_FOUND_VERNUM" -ge "50200"; then
23+
AC_MSG_RESULT(yes. found $PHP_FTDI_FOUND_VERSION)
24+
else
25+
AC_MSG_ERROR(no. found $PHP_FTDI_FOUND_VERSION)
26+
fi
27+
28+
AC_MSG_CHECKING([for ftdi.h header])
29+
for i in $PHP_FTDI /usr/local /usr;
30+
do
31+
test -r $i/include/ftdi.h && FTDI_PREFIX=$i && FTDI_INC_DIR=$i/include/ && FTDI_OK=1
32+
done
33+
34+
if test "$FTDI_OK" != "1"; then
35+
AC_MSG_ERROR([Unable to find ftdi.h])
36+
fi
37+
38+
AC_MSG_RESULT([found in $FTDI_INC_DIR])
39+
40+
AC_MSG_CHECKING([for libftdi shared libraries])
41+
PHP_CHECK_LIBRARY(ftdi, ftdi_init, [
42+
PHP_ADD_LIBRARY_WITH_PATH(ftdi, $FTDI_PREFIX/lib, FTDI_SHARED_LIBADD)
43+
PHP_ADD_INCLUDE($FTDI_INC_DIR)
44+
],[
45+
AC_MSG_ERROR([not found. Make sure that libftdi is installed])
46+
],[
47+
FTDI_SHARED_LIBADD -lftdi
48+
])
49+
50+
PHP_NEW_EXTENSION(ftdi, ftdi.c, $ext_shared)
51+
AC_DEFINE(HAVE_FTDI,1,[ ])
52+
53+
PHP_SUBST(FTDI_SHARED_LIBADD)
54+
fi
55+

examples/Ftdi/UsbDevice.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Ftdi;
4+
5+
class UsbDevice()
6+
{
7+
const BITMODE_BITBANG = FTDI_BITMODE_BITBANG;
8+
const BITMODE_CBUS = FTDI_BITMODE_CBUS;
9+
const BITMODE_MCU = FTDI_BITMODE_MCU;
10+
const BITMODE_OPTO = FTDI_BITMODE_OPTO;
11+
const BITMODE_RESET = FTDI_BITMODE_RESET;
12+
const BITMODE_SYNCBB = FTDI_BITMODE_SYNCBB;
13+
const BITMODE_SYNCFF = FTDI_BITMODE_SYNCFF;
14+
15+
protected $vendorId, $productId;
16+
17+
public function __construct($vendorId, $productId)
18+
{
19+
$this->vendorId = $vendorId;
20+
$this->productId = $productId;
21+
$this->handle = ftdi_init();
22+
}
23+
24+
public function setBitMode($mask, $mode)
25+
{
26+
ftdi_set_bitmode($this->handle, $mask, $mode);
27+
}
28+
29+
public function write($data)
30+
{
31+
ftdi_write_data($this->handle, $data);
32+
}
33+
34+
public function __destruct()
35+
{
36+
ftdi_usb_close($this->handle);
37+
}
38+
}

examples/simple.php

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
try {
4+
$ftdi = ftdi_init();
5+
6+
ftdi_usb_open($ftdi, 0x0403, 0x6001);
7+
ftdi_set_bitmode($ftdi, 0xff, FTDI_BITMODE_BITBANG);
8+
ftdi_write_data($ftdi, 0);
9+
10+
} catch (Exception $e) {
11+
var_dump($e);
12+
}
13+

ftdi.c

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#ifdef HAVE_CONFIG_H
2+
#include "config.h"
3+
#endif
4+
#include "php.h"
5+
#include "php_ini.h"
6+
7+
#include <ftdi.h>
8+
#include "php_ftdi.h"
9+
10+
/* resource list entry */
11+
static int le_php_ftdi_context;
12+
/* exception class entry */
13+
static zend_class_entry *php_ftdi_exception_sc_entry;
14+
15+
/* resource destructor */
16+
static void php_ftdi_context_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
17+
{
18+
struct ftdi_context *context = (struct ftdi_context*) rsrc->ptr;
19+
20+
if (context) {
21+
ftdi_usb_close(context);
22+
ftdi_free(context);
23+
}
24+
}
25+
26+
ZEND_MINIT_FUNCTION(php_ftdi) {
27+
le_php_ftdi_context = zend_register_list_destructors_ex(
28+
php_ftdi_context_dtor, NULL, PHP_FTDI_CONTEXT_RES_NAME, module_number
29+
);
30+
31+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_BITBANG", BITMODE_BITBANG, CONST_CS | CONST_PERSISTENT);
32+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_CBUS", BITMODE_CBUS, CONST_CS | CONST_PERSISTENT);
33+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_MCU", BITMODE_MCU, CONST_CS | CONST_PERSISTENT);
34+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_MPSSE", BITMODE_MPSSE, CONST_CS | CONST_PERSISTENT);
35+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_OPTO", BITMODE_OPTO, CONST_CS | CONST_PERSISTENT);
36+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_RESET", BITMODE_RESET, CONST_CS | CONST_PERSISTENT);
37+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_SYNCBB", BITMODE_SYNCBB, CONST_CS | CONST_PERSISTENT);
38+
REGISTER_LONG_CONSTANT("FTDI_BITMODE_SYNCFF", BITMODE_SYNCFF, CONST_CS | CONST_PERSISTENT);
39+
40+
return SUCCESS;
41+
}
42+
43+
ZEND_NAMED_FUNCTION(php_ftdi_init)
44+
{
45+
struct ftdi_context *context = ftdi_new();
46+
int resource_id;
47+
48+
ftdi_init(context);
49+
50+
resource_id = ZEND_REGISTER_RESOURCE(return_value, context, le_php_ftdi_context);
51+
52+
unsigned char data = 64;
53+
54+
RETURN_RESOURCE(resource_id);
55+
}
56+
57+
ZEND_NAMED_FUNCTION(php_ftdi_usb_open)
58+
{
59+
struct ftdi_context *context;
60+
long vendor_id = 0;
61+
long product_id = 0;
62+
zval *zcontext;
63+
int ret = -1;
64+
65+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &zcontext, &vendor_id, &product_id) == FAILURE) {
66+
return;
67+
}
68+
69+
ZEND_FETCH_RESOURCE(context, struct ftdi_context*, &zcontext, -1, PHP_FTDI_CONTEXT_RES_NAME, le_php_ftdi_context);
70+
71+
ret = ftdi_usb_open(context, vendor_id, product_id);
72+
73+
if (ret != 0) {
74+
PHP_FTDI_THROW(context, ret);
75+
}
76+
77+
RETURN_LONG((long) ret);
78+
}
79+
80+
ZEND_NAMED_FUNCTION(php_ftdi_usb_close)
81+
{
82+
struct ftdi_context *context;
83+
zval *zcontext;
84+
int ret = -1;
85+
86+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zcontext) == FAILURE) {
87+
return;
88+
}
89+
90+
ZEND_FETCH_RESOURCE(context, struct ftdi_context*, &zcontext, -1, PHP_FTDI_CONTEXT_RES_NAME, le_php_ftdi_context);
91+
92+
ret = ftdi_usb_close(context);
93+
94+
if (ret != 0) {
95+
PHP_FTDI_THROW(context, ret);
96+
}
97+
98+
RETURN_LONG((long) ret);
99+
}
100+
101+
ZEND_NAMED_FUNCTION(php_ftdi_set_bitmode)
102+
{
103+
struct ftdi_context *context;
104+
long bitmask;
105+
long mode;
106+
zval *zcontext;
107+
int ret = -1;
108+
109+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &zcontext, &bitmask, &mode) == FAILURE) {
110+
return;
111+
}
112+
113+
ZEND_FETCH_RESOURCE(context, struct ftdi_context*, &zcontext, -1, PHP_FTDI_CONTEXT_RES_NAME, le_php_ftdi_context);
114+
115+
ret = ftdi_set_bitmode(context, bitmask, mode);
116+
117+
if (ret != 0) {
118+
PHP_FTDI_THROW(context, ret);
119+
}
120+
121+
RETURN_LONG((long) ret);
122+
}
123+
124+
ZEND_NAMED_FUNCTION(php_ftdi_free)
125+
{
126+
struct ftdi_context *context;
127+
zval *zcontext;
128+
129+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &zcontext) == FAILURE) {
130+
return;
131+
}
132+
133+
ZEND_FETCH_RESOURCE(context, struct ftdi_context*, &zcontext, -1, PHP_FTDI_CONTEXT_RES_NAME, le_php_ftdi_context);
134+
135+
ftdi_free(context);
136+
}
137+
138+
ZEND_NAMED_FUNCTION(php_ftdi_write_data)
139+
{
140+
struct ftdi_context *context;
141+
long *buf = NULL;
142+
int ret = -1;
143+
zval *zcontext;
144+
unsigned char data;
145+
146+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zcontext, &buf) == FAILURE) {
147+
return;
148+
}
149+
150+
data = (unsigned char) (long) buf;
151+
152+
ZEND_FETCH_RESOURCE(context, struct ftdi_context*, &zcontext, -1, PHP_FTDI_CONTEXT_RES_NAME, le_php_ftdi_context);
153+
154+
/* -666 device unavailable, <0 error code from usb_bulk_write, >0 number of bytes written */
155+
ret = ftdi_write_data(context, &data, sizeof(data));
156+
157+
if (ret < 0) {
158+
PHP_FTDI_THROW(context, ret);
159+
}
160+
161+
RETURN_LONG((long) ret);
162+
}
163+
164+
zend_function_entry php_ftdi_functions[] = {
165+
ZEND_NAMED_FE(ftdi_init, php_ftdi_init, NULL)
166+
ZEND_NAMED_FE(ftdi_usb_open, php_ftdi_usb_open, NULL)
167+
ZEND_NAMED_FE(ftdi_usb_close, php_ftdi_usb_close, NULL)
168+
ZEND_NAMED_FE(ftdi_set_bitmode, php_ftdi_set_bitmode, NULL)
169+
ZEND_NAMED_FE(ftdi_write_data, php_ftdi_write_data, NULL)
170+
ZEND_NAMED_FE(ftdi_free, php_ftdi_free, NULL)
171+
{ NULL, NULL, NULL }
172+
};
173+
174+
zend_module_entry php_ftdi_module_entry = {
175+
STANDARD_MODULE_HEADER,
176+
PHP_FTDI_EXTNAME,
177+
php_ftdi_functions,
178+
PHP_MINIT(php_ftdi),
179+
NULL,
180+
NULL,
181+
NULL,
182+
NULL,
183+
PHP_FTDI_VERSION,
184+
STANDARD_MODULE_PROPERTIES
185+
};
186+
187+
ZEND_GET_MODULE(php_ftdi)

php_ftdi.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef PHP_FTDI_H
2+
#define PHP_FTDI_H 1
3+
4+
#define PHP_FTDI_EXTNAME "ftdi"
5+
#define PHP_FTDI_VERSION "0.01"
6+
7+
#define PHP_FTDI_CONTEXT_RES_NAME "FTDIContext"
8+
9+
extern zend_module_entry php_ftdi_module_entry;
10+
#define phpext_ftdi_ptr &php_ftdi_module_entry
11+
12+
13+
#define PHP_FTDI_THROW(context, code) \
14+
zend_throw_exception(php_ftdi_exception_sc_entry, ftdi_get_error_string(context), (long)code TSRMLS_CC); \
15+
return;
16+
#endif

0 commit comments

Comments
 (0)