[Armadeus-commitlog] armadeus branch, master, updated. armadeus-6.0-427-ge862eeb35
Brought to you by:
sszy
|
From: Julien B a. A. <ar...@us...> - 2018-06-27 17:33:21
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via e862eeb35b8a1b75bc7d3f5dbef364e6bdf4ffaa (commit)
via 272f6a695c45661ecd4d49844b5060d94f4b250b (commit)
via 42365f4ac961500b8a4d7b42a035f264b7f8dc52 (commit)
via dfd98a7cf6447d35513f38888201dbc1ebe47a48 (commit)
from 8a52d62f1ce933abc0065aa17ac07cf5fda36917 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e862eeb35b8a1b75bc7d3f5dbef364e6bdf4ffaa
Author: Julien BOIBESSOT <jul...@ar...>
Date: Wed Jun 27 19:31:13 2018 +0200
[DEMOS] capture: add possibilities to choose SoC input mode and sensor capture mode (mostly of use on i.MX6 and OV5640)
commit 272f6a695c45661ecd4d49844b5060d94f4b250b
Author: Julien BOIBESSOT <jul...@ar...>
Date: Wed Jun 27 15:43:57 2018 +0200
[DEMOS] capture: cleanup & trace improving
commit 42365f4ac961500b8a4d7b42a035f264b7f8dc52
Author: Julien BOIBESSOT <jul...@ar...>
Date: Wed Jun 27 15:41:22 2018 +0200
[PACKAGES] Add a tool to read/modify OV5640 registers from userspace
commit dfd98a7cf6447d35513f38888201dbc1ebe47a48
Author: Julien BOIBESSOT <jul...@ar...>
Date: Mon Jun 4 15:11:15 2018 +0200
[BUILDROOT] 2017.02.x: update cleanup_buildroot.sh
-----------------------------------------------------------------------
Summary of changes:
patches/buildroot/2017.02/cleanup_buildroot.sh | 13 +-
target/demos/camera/capture/capture.c | 188 +++++++++++-----
target/packages/ov5640ctrl/Makefile | 27 +++
target/packages/ov5640ctrl/ov5640.c | 290 +++++++++++++++++++++++++
4 files changed, 465 insertions(+), 53 deletions(-)
create mode 100644 target/packages/ov5640ctrl/Makefile
create mode 100644 target/packages/ov5640ctrl/ov5640.c
diff --git a/patches/buildroot/2017.02/cleanup_buildroot.sh b/patches/buildroot/2017.02/cleanup_buildroot.sh
index 0aba335e8..0c1ca60cf 100755
--- a/patches/buildroot/2017.02/cleanup_buildroot.sh
+++ b/patches/buildroot/2017.02/cleanup_buildroot.sh
@@ -79,9 +79,20 @@ rm -rf buildroot/package/libpng/libpng.hash
rm -rf buildroot/package/libpng/libpng.mk
rm -rf buildroot/package/libqmi/libqmi.hash
rm -rf buildroot/package/libqmi/libqmi.mk
-# For 2017.02.5 -> 2017.02.10 bump
+# For 2017.02.5 -> 2017.02.1x bump
rm -rf buildroot/package/libxml2/0001-Fix-XPointer-paths-beginning-with-range-to.patch
rm -rf buildroot/package/libxml2/0002-Disallow-namespace-nodes-in-XPointer-ranges.patch
+rm -rf buildroot/package/qt/0001-configure.patch
+rm -rf buildroot/package/qt/0002-eglwsegl-use-system.patch
+rm -rf buildroot/package/qt/0003-fix-const-atomics.patch
+rm -rf buildroot/package/qt/0004-pthread_getattr_np.patch
+rm -rf buildroot/package/qt/0005-script-qtdbus-no-gui.patch
+rm -rf buildroot/package/qt/0006-Add-initial-support-of-ARC-architecture.patch
+rm -rf buildroot/package/qt/0007-Prevent-unaligned-access-on-ARC.patch
+rm -rf buildroot/package/qt/0008-Fix-conversion-constructor-error-for-legacy-c-compil.patch
+rm -rf buildroot/package/qt/0009-Fix-library-inclusion-order-when-building-statically.patch
+rm -rf buildroot/package/qt/0010-Fix-for-platform-socklen_t-on-other-C-libraries-than.patch
+rm -rf buildroot/package/qt/0012-OpenGL-EGL-Avoid-X11-header-collision.patch
#
rm -rf buildroot/package/linux-headers/2.6.29.6/0001-net-Support-inclusion-of-linux-socket.h-before-sys-s.patch
rm -rf buildroot/package/linux-headers/2.6.29.6/368-redhat-types_h-define-__aligned_u64-and-expose-to-userspace.patch
diff --git a/target/demos/camera/capture/capture.c b/target/demos/camera/capture/capture.c
index f0ce152b2..3cdf68b55 100644
--- a/target/demos/camera/capture/capture.c
+++ b/target/demos/camera/capture/capture.c
@@ -61,12 +61,12 @@ struct buffer {
size_t offset;
};
-static char *dev_name = NULL;
-static char *ip_addr = "192.168.0.2";
-static io_method io = IO_METHOD_MMAP;
-static int fd = -1;
-struct buffer * buffers = NULL;
-static unsigned int n_buffers = 0;
+static char *dev_name = NULL;
+static char *ip_addr = "192.168.0.2";
+static io_method io = IO_METHOD_MMAP;
+static int v4l_fd = -1;
+struct buffer *buffers = NULL;
+static unsigned int n_buffers = 0;
int g_use_codec = 0;
static int debug = 0;
@@ -83,6 +83,8 @@ struct camera {
struct camera mycamera;
unsigned int force_yuv420 = 0;
+unsigned int video_input = 0;
+unsigned int capture_mode = 0;
#define FOURCC_TO_STR(fmt) fmt & 0xff, (fmt >> 8) & 0xff, (fmt >> 16) & 0xff, (fmt >> 24) & 0xff
@@ -504,7 +506,7 @@ static int read_frame(void)
switch (io) {
case IO_METHOD_READ:
- if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
+ if (-1 == read(v4l_fd, buffers[0].start, buffers[0].length)) {
switch (errno) {
case EAGAIN:
return 0;
@@ -529,7 +531,7 @@ static int read_frame(void)
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
- if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return 0;
@@ -557,7 +559,7 @@ static int read_frame(void)
// else
process_image(buffers[buf.index].start, buf.length);
- if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
+ if (-1 == xioctl(v4l_fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
break;
@@ -568,7 +570,7 @@ static int read_frame(void)
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_USERPTR;
- if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
case EAGAIN:
return 0;
@@ -592,7 +594,7 @@ static int read_frame(void)
process_image((void *) buf.m.userptr, 0);
- if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
+ if (-1 == xioctl(v4l_fd, VIDIOC_QBUF, &buf))
errno_exit ("VIDIOC_QBUF");
break;
@@ -617,13 +619,13 @@ static void mainloop(void)
int r;
FD_ZERO (&fds);
- FD_SET (fd, &fds);
+ FD_SET (v4l_fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
- r = select(fd + 1, &fds, NULL, NULL, &tv);
+ r = select(v4l_fd + 1, &fds, NULL, NULL, &tv);
if (-1 == r) {
if (EINTR == errno)
@@ -682,7 +684,7 @@ static void stop_capturing(void)
case IO_METHOD_USERPTR:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))
+ if (-1 == xioctl(v4l_fd, VIDIOC_STREAMOFF, &type))
errno_exit ("VIDIOC_STREAMOFF");
break;
@@ -709,13 +711,13 @@ static void start_capturing(void)
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
- if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
+ if (-1 == xioctl(v4l_fd, VIDIOC_QBUF, &buf))
errno_exit ("VIDIOC_QBUF");
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
+ if (-1 == xioctl(v4l_fd, VIDIOC_STREAMON, &type))
errno_exit ("VIDIOC_STREAMON");
break;
@@ -732,13 +734,13 @@ static void start_capturing(void)
buf.m.userptr = (unsigned long) buffers[i].start;
buf.length = buffers[i].length;
- if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
+ if (-1 == xioctl(v4l_fd, VIDIOC_QBUF, &buf))
errno_exit ("VIDIOC_QBUF");
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
+ if (-1 == xioctl(v4l_fd, VIDIOC_STREAMON, &type))
errno_exit ("VIDIOC_STREAMON");
break;
@@ -797,7 +799,7 @@ static void init_mmap(void)
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
- if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf (stderr, "%s does not support "
"memory mapping\n", dev_name);
@@ -829,7 +831,7 @@ static void init_mmap(void)
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
- if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
+ if (-1 == xioctl(v4l_fd, VIDIOC_QUERYBUF, &buf))
errno_exit ("VIDIOC_QUERYBUF");
buffers[n_buffers].length = buf.length;
@@ -839,7 +841,7 @@ static void init_mmap(void)
buf.length,
PROT_READ | PROT_WRITE /* required */,
MAP_SHARED /* recommended */,
- fd, buf.m.offset);
+ v4l_fd, buf.m.offset);
/*printf("### start= 0x%08x offset=0x%08x\n", (unsigned int)(buffers[n_buffers].start), buffers[n_buffers].offset);*/
if (MAP_FAILED == buffers[n_buffers].start)
errno_exit ("mmap");
@@ -860,7 +862,7 @@ static void init_userp(unsigned int buffer_size)
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_USERPTR;
- if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
fprintf (stderr, "%s does not support "
"user pointer i/o\n", dev_name);
@@ -892,6 +894,9 @@ static void init_userp(unsigned int buffer_size)
static Uint32 get_a_supported_pix_fmt(void)
{
struct v4l2_fmtdesc fmtdesc;
+ struct v4l2_frmsizeenum fszenum;
+ struct v4l2_streamparm parm;
+ Uint32 ret = 0;
int i;
/* First check if a LCD native format is available (-> no need for CSC) */
@@ -899,18 +904,21 @@ static Uint32 get_a_supported_pix_fmt(void)
CLEAR(fmtdesc);
fmtdesc.index = i;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
+ if (-1 == ioctl(v4l_fd, VIDIOC_ENUM_FMT, &fmtdesc))
break;
if (debug) {
- fprintf(stdout, "Trying format %d %c%c%c%c (%s)\n",
- fmtdesc.index, FOURCC_TO_STR(fmtdesc.pixelformat),
- fmtdesc.description);
+ fprintf(stdout, "Camera supports %c%c%c%c (%s) as format %d\n",
+ FOURCC_TO_STR(fmtdesc.pixelformat),
+ fmtdesc.description,
+ fmtdesc.index
+ );
}
if ((fmtdesc.pixelformat == V4L2_PIX_FMT_RGB565) ||
(fmtdesc.pixelformat == V4L2_PIX_FMT_RGB32) ||
(fmtdesc.pixelformat == V4L2_PIX_FMT_RGB24) ) {
- fprintf(stdout, "Using img format (%d %c%c%c%c)\n", i, FOURCC_TO_STR(fmtdesc.pixelformat));
- return fmtdesc.pixelformat;
+ fprintf(stdout, "Using camera format %d (%c%c%c%c)\n", i, FOURCC_TO_STR(fmtdesc.pixelformat));
+ ret = fmtdesc.pixelformat;
+ goto end_of_fmt;
}
}
@@ -919,7 +927,7 @@ static Uint32 get_a_supported_pix_fmt(void)
CLEAR(fmtdesc);
fmtdesc.index = i;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
+ if (-1 == ioctl(v4l_fd, VIDIOC_ENUM_FMT, &fmtdesc))
break;
if ((fmtdesc.pixelformat == V4L2_PIX_FMT_YUYV)
@@ -938,11 +946,74 @@ static Uint32 get_a_supported_pix_fmt(void)
else
fprintf(stdout, "??? \n");
- return fmtdesc.pixelformat;
+ ret = fmtdesc.pixelformat;
+ goto end_of_fmt;
}
}
- return 0;
+end_of_fmt:
+
+ fprintf(stdout, "For selected pixel format, camera supports "
+ "following framesizes:\n");
+ for (i = 0;; i++) {
+ CLEAR(fszenum);
+ fszenum.index = i;
+ fszenum.pixel_format = fmtdesc.pixelformat;
+ if (-1 == ioctl(v4l_fd, VIDIOC_ENUM_FRAMESIZES, &fszenum)) {
+ break;
+ } else {
+ fprintf(stdout, "- number %d of type %d (%dx%d)\n",
+ fszenum.index,
+ fszenum.type,
+ fszenum.discrete.width,
+ fszenum.discrete.height
+ );
+ }
+ }
+
+ if (capture_mode) {
+ CLEAR(parm);
+ parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ parm.parm.capture.timeperframe.numerator = 30;
+ parm.parm.capture.timeperframe.denominator = 1;
+ parm.parm.capture.capturemode = capture_mode;
+ fprintf(stdout, "Forcing sensor capture mode to %d\n", capture_mode);
+ if (ioctl(v4l_fd, VIDIOC_S_PARM, &parm) < 0) {
+ fprintf(stderr, "VIDIOC_S_PARM failed: %s", strerror(errno));
+ }
+ }
+
+ return ret;
+}
+
+static void select_video_input(void)
+{
+ struct v4l2_input input;
+ int i = 0;
+ int selected_input;
+
+ for (i = 0;; i++) {
+ CLEAR(input);
+ input.index = i;
+ if (-1 == xioctl(v4l_fd, VIDIOC_ENUMINPUT, &input)) {
+ break;
+ } else {
+ fprintf(stdout, "Video input %d is (\'%s\') \n",
+ input.index,
+ input.name
+ );
+ }
+ }
+ if (video_input) {
+ /* OK, I agree, it's not really a dynamic selection ;-) */
+ selected_input = video_input;
+ fprintf(stdout, "Forcing video input to %d\n", selected_input);
+ if (ioctl(v4l_fd, VIDIOC_S_INPUT, &selected_input) < 0) {
+ fprintf(stderr, "Failed to set video input !\n");
+ }
+ } else {
+ fprintf(stdout, "if you want to choose video input (if many), use -i option.\n");
+ }
}
static void init_capture_device(unsigned int capt_width, unsigned int capt_height)
@@ -953,7 +1024,7 @@ static void init_capture_device(unsigned int capt_width, unsigned int capt_heigh
struct v4l2_format fmt;
unsigned int min;
- if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
fprintf(stderr, "%s is no V4L2 device\n",
dev_name);
@@ -993,15 +1064,16 @@ static void init_capture_device(unsigned int capt_width, unsigned int capt_heigh
/* Select video input, video standard and tune here. */
+ select_video_input();
CLEAR(cropcap);
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
+ if (0 == xioctl (v4l_fd, VIDIOC_CROPCAP, &cropcap)) {
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */
- if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
+ if (-1 == xioctl(v4l_fd, VIDIOC_S_CROP, &crop)) {
switch (errno) {
case EINVAL:
/* Cropping not supported. */
@@ -1033,7 +1105,7 @@ static void init_capture_device(unsigned int capt_width, unsigned int capt_heigh
fmt.fmt.pix.height = capt_height;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
+ if (-1 == xioctl(v4l_fd, VIDIOC_S_FMT, &fmt))
errno_exit("VIDIOC_S_FMT");
/* Note VIDIOC_S_FMT may change width and height. */
@@ -1073,10 +1145,10 @@ static void init_capture_device(unsigned int capt_width, unsigned int capt_heigh
static void close_device(void)
{
- if (-1 == close (fd))
+ if (-1 == close(v4l_fd))
errno_exit("close");
- fd = -1;
+ v4l_fd = -1;
}
static void open_capture_device(void)
@@ -1094,9 +1166,9 @@ static void open_capture_device(void)
exit(EXIT_FAILURE);
}
- fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
+ v4l_fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
- if (-1 == fd) {
+ if (-1 == v4l_fd) {
fprintf(stderr, "Cannot open '%s': %d, %s\n",
dev_name, errno, strerror (errno));
exit(EXIT_FAILURE);
@@ -1108,28 +1180,32 @@ static void usage(FILE *fp, int argc, char **argv)
fprintf (fp,
"Usage: %s [options]\n\n"
"Options:\n"
- " -d | --device name Video device name [/dev/video0]\n"
- " -h | --help Print this message\n"
- " -m | --mmap Use memory mapped buffers\n"
- " -r | --read Use read() calls\n"
- " -u | --userp Use application allocated buffers\n"
- " --width W Use W as screen width (instead of %d)\n"
- " --height H Use H as screen height (instead of %d)\n"
- " --cam_width W Use W as camera picture width (instead of %d)\n"
- " --cam_height H Use H as camera picture height (instead of %d)\n"
- " --use_vpu IP Uses processor VPU to encode video (at camera size) and send it to IP addr\n"
- " -f | --force Forces YUV420/YU12 format on camera\n"
- " -b | --verbose Display some debug informations\n"
+ " -d | --device name Video device name [/dev/video0]\n"
+ " -h | --help Print this message\n"
+ " -i | --input Use given video input (if many, 0 by default)\n"
+ " -o | --capture_mode I Use given capture mode [0-8] of sensor (if supported)\n"
+ " -m | --mmap Use memory mapped buffers\n"
+ " -r | --read Use read() calls\n"
+ " -u | --userp Use application allocated buffers\n"
+ " --width W Use W as screen width (instead of %d)\n"
+ " --height H Use H as screen height (instead of %d)\n"
+ " --cam_width W Use W as camera picture width (instead of %d)\n"
+ " --cam_height H Use H as camera picture height (instead of %d)\n"
+ " --use_vpu IP Uses processor VPU to encode video (at camera size) and send it to IP addr\n"
+ " -f | --force Forces YUV420/YU12 format on camera\n"
+ " -b | --verbose Display some debug informations\n"
"",
argv[0], SCREEN_WIDTH, SCREEN_HEIGHT, CAM_WIDTH, CAM_HEIGHT);
}
-static const char short_options [] = "d:hmruwtfb";
+static const char short_options [] = "d:hi:mo:ruwtfb";
static const struct option long_options [] = {
{ "device", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
+ { "input", required_argument, NULL, 'i' },
{ "mmap", no_argument, NULL, 'm' },
+ { "capture_mode",required_argument, NULL, 'o' },
{ "read", no_argument, NULL, 'r' },
{ "userp", no_argument, NULL, 'u' },
{ "width", required_argument, NULL, 'w' },
@@ -1206,10 +1282,18 @@ int main(int argc, char **argv)
usage(stdout, argc, argv);
exit(EXIT_SUCCESS);
+ case 'i':
+ video_input = atoi(optarg);
+ break;
+
case 'm':
io = IO_METHOD_MMAP;
break;
+ case 'o':
+ capture_mode = atoi(optarg);
+ break;
+
case 'r':
io = IO_METHOD_READ;
break;
diff --git a/target/packages/ov5640ctrl/Makefile b/target/packages/ov5640ctrl/Makefile
new file mode 100644
index 000000000..6aced9770
--- /dev/null
+++ b/target/packages/ov5640ctrl/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for the Armadeus OV5640 test tool
+#
+
+PWD := $(shell pwd)
+CC = $(PWD)/../../../buildroot/output/host/usr/bin/arm-linux-gcc
+
+CFLAGS = -Wall -O
+SOURCES = $(wildcard *.c)
+OBJECTS = $(SOURCES:.c=.o)
+EXE = ov5640ctrl
+
+all: $(EXE)
+
+%.o: %.c
+ @echo " CC " $@
+ @$(CC) -c $(CFLAGS) $^
+
+$(EXE): $(OBJECTS)
+ @echo " LD " $@
+ @$(CC) $(OBJECTS) $(LDFLAGS) -o $@
+
+clean:
+ -rm -f $(EXE)
+ -rm -f *.o
+
+.PHONY: clean
diff --git a/target/packages/ov5640ctrl/ov5640.c b/target/packages/ov5640ctrl/ov5640.c
new file mode 100644
index 000000000..b2799b5fb
--- /dev/null
+++ b/target/packages/ov5640ctrl/ov5640.c
@@ -0,0 +1,290 @@
+/*
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+
+#define DEBUG_OV5640 1
+
+#define VERSION "0.1"
+#define CONF_FILE "ov5640.conf"
+#define MAX_DUMP_LINE 100
+
+#define OV5640_I2C_SLAVE_ADDR 0x3c
+
+#define CHIP_REVISION 0x302a
+
+void usage(char *name)
+{
+ printf("\n%s utility, version %s \n", name, VERSION);
+ printf("q: quit\n");
+ printf("r: read a register\n");
+ printf("w: write to a register\n");
+ printf("u: move ROI up\n");
+ printf("h: move ROI left (from sensor PoW)\n");
+ printf("j: move ROI right (from sensor PoW)\n");
+ printf("n: move ROI down\n");
+ printf("d: dump some OV5640 registers\n");
+ printf("s: save\n");
+ printf("l: load\n");
+ printf("other: this menu\n");
+}
+
+int read_reg(int i2c_fd, unsigned int reg, unsigned char *rbuf)
+{
+ unsigned char buf[2];
+ int ret;
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+
+ ret = write(i2c_fd, buf, 2);
+ if (ret < 0) {
+ perror("read_reg, setting reg addr");
+ return ret;
+ }
+ read(i2c_fd, rbuf, 1);
+
+ fprintf(stdout, "read 0x%02x @ 0x%02x%02x\n", rbuf[0], buf[0], buf[1]);
+
+ return 0;
+}
+
+int write_reg(int i2c_fd, unsigned int reg, unsigned char value)
+{
+ int ret = 0;
+ int len = 3;
+
+ unsigned char buf[3];
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = value;
+
+ fprintf(stdout, "writing 0x%02x @ 0x%02x%02x\n", value, buf[0], buf[1]);
+
+ ret = write(i2c_fd, buf, len);
+ if (ret < 0) {
+ fprintf(stderr, "Error: Write failed\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+void dump(int fd, FILE* destFile)
+{
+ int i;
+ unsigned char buf[2];
+
+ for (i = 0; i < 16; i++) {
+ read_reg(fd, 0x3800 + i, buf);
+ }
+}
+
+void move_roi(int fd, int x_off, int y_off)
+{
+ static unsigned int x_addr_st = 0x150;
+ static unsigned int x_add_end = 0x8ef;
+ static unsigned int y_addr_st = 0x1b2;
+ static unsigned int y_add_end = 0x5f1;
+
+ if (!x_off)
+ goto process_y_off;
+
+ if (x_addr_st >= abs(x_off)) {
+ x_addr_st += x_off;
+ x_add_end += x_off;
+ } else {
+ fprintf(stdout, "you reached limit of Xoff\n");
+ goto no_write_reg;
+ }
+
+ write_reg(fd, 0x3800, x_addr_st >> 8);
+ write_reg(fd, 0x3801, x_addr_st & 0xff);
+ write_reg(fd, 0x3804, x_add_end >> 8);
+ write_reg(fd, 0x3805, x_add_end & 0xff);
+
+process_y_off:
+
+ if (y_addr_st >= abs(y_off)) {
+ y_addr_st += y_off;
+ y_add_end += y_off;
+ } else {
+ fprintf(stdout, "you reached limit of Yoff\n");
+ goto no_write_reg;
+ }
+
+ write_reg(fd, 0x3802, y_addr_st >> 8);
+ write_reg(fd, 0x3803, y_addr_st & 0xff);
+ write_reg(fd, 0x3806, y_add_end >> 8);
+ write_reg(fd, 0x3807, y_add_end & 0xff);
+
+no_write_reg:
+ return;
+}
+
+void write_regs_from_file(int fd, char* fileName)
+{
+ char line[MAX_DUMP_LINE];
+ char tempFileName[MAX_DUMP_LINE];
+ FILE *fd_conf = NULL;
+ int addr, val, nb = 0;
+
+ if (strlen(fileName) == 0) {
+ printf("Enter file name: ");
+ fgets(tempFileName, sizeof(tempFileName), stdin);
+ tempFileName[strlen(tempFileName)-1] = '\0'; /* suppress \n */
+ } else {
+ strcpy(tempFileName, fileName);
+ }
+
+ if ((fd_conf = fopen(tempFileName, "r")) == NULL) {
+ perror("can't open conf file");
+ return;
+ }
+
+ while (fgets(line, MAX_DUMP_LINE, fd_conf) != NULL) {
+ nb = sscanf(line, "%4X%*c%2X", &addr, &val);
+
+ fprintf(stdout, "--- %04x %02x (%d)\n", addr, val, nb);
+ }
+
+ if (fd_conf != NULL)
+ fclose(fd_conf);
+}
+
+/* taken from i2c-tools : */
+int set_slave_addr(int file, int address, int force)
+{
+ /* With forcei=1, let the user read from/write to the registers
+ even when a driver is also running */
+ if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) {
+ fprintf(stderr,
+ "Error: Could not set address to 0x%02x: %s\n",
+ address, strerror(errno));
+ return -errno;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int i2c_fd;
+ FILE *fd_conf = NULL;
+ char string[10];
+ int regAddr;
+ int regValue;
+ char* bus = "/dev/i2c-0";
+ unsigned char read_buf[2];
+
+ if (argc > 2) { /* too many args */
+ usage(argv[0]);
+ exit(1);
+ } else if (argc == 2) { /* i2c bus */
+ bus = argv[1];
+ }
+
+ if ((i2c_fd = open(bus, O_RDWR)) < 0) {
+ perror("Open error: ");
+ exit (1);
+ }
+
+ set_slave_addr(i2c_fd, OV5640_I2C_SLAVE_ADDR, 1);
+
+ /* check OV5640 presence */
+ if (!read_reg(i2c_fd, CHIP_REVISION, read_buf)) {
+ if (read_buf[0] != 0xb0 ) {
+ printf("OV5640 revision (0x%02x) not supported... Exiting\n", read_buf[0]);
+ exit(1);
+ }
+ } else {
+ printf("OV5640 not found @ 0x%02X... Exiting\n", OV5640_I2C_SLAVE_ADDR);
+ exit(1);
+ }
+
+ usage(argv[0]);
+ while(1) {
+ fprintf(stdout, " > ");
+
+ fgets(string, sizeof(string), stdin);
+
+ if (string[0] == 'q') {
+ exit(0);
+ }
+ else if (string[0] == 'w') {
+ printf("register address (hex without 0x): ");
+ fgets(string, sizeof(string), stdin);
+ sscanf(string, "%4x", ®Addr);
+ printf("register value (hex without 0x): ");
+ fgets(string, sizeof(string), stdin);
+ sscanf(string, "%2x", ®Value);
+ write_reg(i2c_fd, regAddr, regValue);
+ }
+ else if (string[0] == 'r') {
+ printf("register address (hex without 0x): ");
+ fgets(string, sizeof(string), stdin);
+ sscanf(string, "%4x", ®Addr);
+ read_reg(i2c_fd, regAddr, read_buf);
+ }
+ else if (string[0] == 'd') {
+ dump(i2c_fd, fd_conf);
+ }
+ else if (string[0] == 'u') {
+ move_roi(i2c_fd, 0, -30);
+ }
+ else if (string[0] == 'j') {
+ move_roi(i2c_fd, -30, 0);
+ }
+ else if (string[0] == 'h') {
+ move_roi(i2c_fd, 30, 0);
+ }
+ else if (string[0] == 'n') {
+ move_roi(i2c_fd, 0, 30);
+ }
+ else if (string[0] == 's') {
+ if ((fd_conf = fopen(CONF_FILE, "w")) < 0) {
+ perror("Open error: ");
+ exit (1);
+ }
+ /*dump(fd, fd_conf);*/
+ if (fd_conf != NULL) {
+ fclose(fd_conf);
+ }
+ }
+ else if (string[0] == 'l') {
+ write_regs_from_file(i2c_fd, "");
+ } else {
+ usage(argv[0]);
+ }
+ };
+
+ if (i2c_fd >= 0) {
+ close(i2c_fd);
+ }
+
+ exit (0);
+}
hooks/post-receive
--
armadeus
|