summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Component.cdef18
-rw-r--r--README.md62
-rw-r--r--camera.c133
-rw-r--r--camera.h86
4 files changed, 299 insertions, 0 deletions
diff --git a/Component.cdef b/Component.cdef
new file mode 100644
index 0000000..9c3d8ca
--- /dev/null
+++ b/Component.cdef
@@ -0,0 +1,18 @@
+cflags:
+{
+ -std=c99
+}
+
+requires:
+{
+ api:
+ {}
+
+ component:
+ {}
+}
+
+sources:
+{
+ camera.c
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a37159f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,62 @@
+# VC0706-cam-lib-legato
+Library for the Adafruit VC0706 camera used on Legato devices. The majority of this code is ported from Adafruit's [Adafruit-VC0706-Serial-Camera-Library](https://github.com/adafruit/Adafruit-VC0706-Serial-Camera-Library) repository with some C/Legato specific changes.
+
+## Project Status
+
+Still incomplete and not functional. We are hoping to release 1.0.0 in the coming days.
+
+## Usage on Other Platforms
+The Legato serial API [`le_tty`](http://legato.io/legato-docs/latest/le__tty_8h.html) returns a file descriptor used to read and write. The file descriptor in the `Camera` struct can be replaced with any other file descriptor serial interface.
+
+## API
+```c
+void delay (unsigned int secs);
+int openCameraFd ();
+void sendCommand (Camera *cam, byte cmd, byte args[]);
+bool runCommand (Camera *cam, byte cmd, byte args[], int respLen);
+int readResponse (Camera *cam, int nBytes, int timeout);
+bool verifyResponse (Camera *cam, byte cmd);
+bool cameraFrameBuffCtrl (Camera *cam, byte cmd);
+bool takePicture (Camera *cam);
+size_t bufferToFile (Camera *cam, char *path);
+bool reset (Camera *cam);
+bool TVon (Camera *cam);
+bool TVOff (Camera *cam);
+byte *readPicture (Camera *cam);
+bool resumeVideo (Camera *cam);
+uint32_t frameLength (Camera *cam);
+char *getVersion (Camera *cam);
+uint8_t available();
+uint8_t getDownsize(void);
+bool setDownsize(uint8_t);
+int getImageSize (Camera *cam);
+bool setImageSize (Camera *cam, int size);
+bool getMotionDetect (Camera *cam);
+byte getMotionStatus(Camera *cam, byte x);
+bool motionDetected (Camera *cam);
+bool setMotionDetect (bool flag);
+bool setMotionStatus (byte x, byte d1, byte d2);
+byte getCompression (Camera *cam);
+bool setCompression(Camera *cam, byte c);
+bool getPTZ(Camera *cam, uint16_t *w, uint16_t *h, uint16_t *wz, uint16_t *hz, uint16_t *pan, uint16_t *tilt);
+bool setPTZ(Camera *cam, uint16_t wz, uint16_t hz, uint16_t pan, uint16_t tilt);
+```
+
+## Typedefs
+
+### byte
+```c
+typedef uint8_t byte;
+```
+
+### Camera
+```c
+typedef struct {
+ int fd; // file descriptor for the serial port
+ byte serialNum; // camera serial number
+ byte buff[BUFF_SIZE]; // byte array to store camera data
+ int bufferLen; // current length of data in buffer
+ uint16_t frameptr;
+} Camera;
+
+```
diff --git a/camera.c b/camera.c
new file mode 100644
index 0000000..1721522
--- /dev/null
+++ b/camera.c
@@ -0,0 +1,133 @@
+#include "legato.h"
+#include "interfaces.h"
+#include "camera.h"
+#include <time.h>
+
+
+COMPONENT_INIT {
+ Camera cam = {
+ .fd = openCameraFd(),
+ .serialNum = 0x0,
+ .bufferLen = 0,
+ .frameptr = 0
+ };
+ bool success = takePicture(&cam);
+ LE_INFO("Number of bytes in buffer: %d", NUM_ARRAY_MEMBERS(cam.buff));
+ LE_INFO("Did it work: %d", success);
+}
+
+// Used to wait for the serial port
+void delay (unsigned int msecs) {
+ unsigned int secs = msecs / 1000;
+ unsigned int retTime = time(0) + secs;
+ while (time(0) < retTime);
+}
+
+// Returns a file descriptor that can be used to
+// talk to the camera
+int openCameraFd () {
+ int fd = le_tty_Open(SERIAL_PATH, O_RDWR);
+ le_tty_SetBaudRate(fd, CAM_BAUD_RATE);
+ return fd;
+}
+
+// Send a command to the camera serial port
+void sendCommand (Camera *cam, byte cmd, byte args[]) {
+ uint8_t init = VC0706_PREFIX;
+ write(cam->fd, &init, 1); // send the cmd prefix
+ write(cam->fd, &(cam->serialNum), 1); // send the serial number
+ write(cam->fd, &cmd, 1); // send the cmd
+ for(int i = 0; i < NUM_ARRAY_MEMBERS(args); i++) { // send each arg
+ write(cam->fd, &args[i], 1);
+ }
+}
+
+// Run a command
+bool runCommand (Camera *cam, byte cmd, byte args[], int respLen) {
+ sendCommand(cam, cmd, args);
+ if (readResponse(cam, respLen, TIMEOUT) != respLen)
+ return false;
+ if (verifyResponse(cam, cmd))
+ return false;
+ else return true;
+}
+
+// Reads from the camera and returns how many bytes it read
+int readResponse (Camera *cam, int nBytes, int timeout) {
+ int counter = 0;
+ int bufferLen = 0;
+ // read while below timeout and while the buffer
+ // is still smaller than expected
+ while(timeout >= counter && cam->bufferLen <= nBytes) {
+ ssize_t bytesRead = read(cam->fd, &(cam->buff) + cam->bufferLen, 1); // read one byte at a time
+ bufferLen++;
+ // bytesRead will be 0 or -1 if no data was received
+ if (bytesRead <= 0) {
+ delay(1);
+ counter++;
+ continue;
+ }
+ counter = 0;
+ }
+ return cam->bufferLen;
+}
+
+bool verifyResponse (Camera *cam, byte cmd) {
+ // If any of these are not equal than
+ // the command failed
+ return
+ !(cam->buff[0] != VC0706_RESP_PREFIX ||
+ cam->buff[1] != cam->serialNum ||
+ cam->buff[2] != cmd ||
+ cam->buff[3] != 0x0);
+}
+
+bool cameraFrameBuffCtrl (Camera *cam, byte cmd) {
+ byte args[] = { 0x1, cmd };
+ return runCommand(cam, cmd, args, 5);
+}
+
+bool takePicture (Camera *cam) {
+ return cameraFrameBuffCtrl(cam, VC0706_STOPCURRENTFRAME);
+}
+
+bool reset (Camera *cam) {
+ byte args[] = { 0x0 };
+ return runCommand(cam, VC0706_RESET, args, 5);
+}
+
+size_t bufferToFile (Camera *cam, char *path) {
+ FILE *photo = fopen(path, "w");
+ if (photo != NULL) {
+ LE_INFO("File pointer for %s is valid", path);
+ size_t bytesWritten = fwrite(&(cam->buff), sizeof(cam->buff[0]), cam->bufferLen, photo);
+ fclose(photo);
+ return bytesWritten;
+ }
+ else {
+ LE_INFO("File pointer for %s is invalid", path);
+ return -1;
+ }
+}
+
+// TODO implement these
+bool TVon (Camera *cam);
+bool TVOff (Camera *cam);
+byte *readPicture (Camera *cam);
+bool resumeVideo (Camera *cam);
+uint32_t frameLength (Camera *cam);
+char *getVersion (Camera *cam);
+uint8_t available();
+uint8_t getDownsize(void);
+bool setDownsize(uint8_t);
+int getImageSize (Camera *cam);
+bool setImageSize (Camera *cam, int size);
+bool getMotionDetect (Camera *cam);
+byte getMotionStatus(Camera *cam, byte x);
+bool motionDetected (Camera *cam);
+bool setMotionDetect (bool flag);
+bool setMotionStatus (byte x, byte d1, byte d2);
+byte getCompression (Camera *cam);
+bool setCompression(Camera *cam, byte c);
+bool getPTZ(Camera *cam, uint16_t *w, uint16_t *h, uint16_t *wz, uint16_t *hz, uint16_t *pan, uint16_t *tilt);
+bool setPTZ(Camera *cam, uint16_t wz, uint16_t hz, uint16_t pan, uint16_t tilt);
diff --git a/camera.h b/camera.h
new file mode 100644
index 0000000..01e13b7
--- /dev/null
+++ b/camera.h
@@ -0,0 +1,86 @@
+#include "legato.h"
+
+#define VC0706_RESP_PREFIX 0x76
+#define VC0706_PREFIX 0x56
+#define VC0706_RESET 0x26
+#define VC0706_GEN_VERSION 0x11
+#define VC0706_SET_PORT 0x24
+#define VC0706_READ_FBUF 0x32
+#define VC0706_GET_FBUF_LEN 0x34
+#define VC0706_FBUF_CTRL 0x36
+#define VC0706_DOWNSIZE_CTRL 0x54
+#define VC0706_DOWNSIZE_STATUS 0x55
+#define VC0706_READ_DATA 0x30
+#define VC0706_WRITE_DATA 0x31
+#define VC0706_COMM_MOTION_CTRL 0x37
+#define VC0706_COMM_MOTION_STATUS 0x38
+#define VC0706_COMM_MOTION_DETECTED 0x39
+#define VC0706_MOTION_CTRL 0x42
+#define VC0706_MOTION_STATUS 0x43
+#define VC0706_TVOUT_CTRL 0x44
+#define VC0706_OSD_ADD_CHAR 0x45
+
+#define VC0706_STOPCURRENTFRAME 0x0
+#define VC0706_STOPNEXTFRAME 0x1
+#define VC0706_RESUMEFRAME 0x3
+#define VC0706_STEPFRAME 0x2
+
+#define VC0706_640x480 0x00
+#define VC0706_320x240 0x11
+#define VC0706_160x120 0x22
+
+#define VC0706_MOTIONCONTROL 0x0
+#define VC0706_UARTMOTION 0x01
+#define VC0706_ACTIVATEMOTION 0x01
+
+#define VC0706_SET_ZOOM 0x52
+#define VC0706_GET_ZOOM 0x53
+
+#define CAM_BAUD_RATE LE_TTY_SPEED_38400
+#define BUFF_SIZE 1000
+#define DELAY 10
+#define TIMEOUT 200
+#define CAM_SERIAL 0
+
+static const char SERIAL_PATH[] = "/dev/ttyHS0";
+
+typedef uint8_t byte;
+
+typedef struct {
+ int fd; // file descriptor for the serial port
+ byte serialNum; // camera serial number
+ byte buff[BUFF_SIZE]; // byte array to store camera data
+ int bufferLen; // current length of data in buffer
+ uint16_t frameptr;
+} Camera;
+
+void delay (unsigned int secs);
+int openCameraFd ();
+void sendCommand (Camera *cam, byte cmd, byte args[]);
+bool runCommand (Camera *cam, byte cmd, byte args[], int respLen);
+int readResponse (Camera *cam, int nBytes, int timeout);
+bool verifyResponse (Camera *cam, byte cmd);
+bool cameraFrameBuffCtrl (Camera *cam, byte cmd);
+bool takePicture (Camera *cam);
+size_t bufferToFile (Camera *cam, char *path);
+bool reset (Camera *cam);
+bool TVon (Camera *cam);
+bool TVOff (Camera *cam);
+byte *readPicture (Camera *cam);
+bool resumeVideo (Camera *cam);
+uint32_t frameLength (Camera *cam);
+char *getVersion (Camera *cam);
+uint8_t available();
+uint8_t getDownsize(void);
+bool setDownsize(uint8_t);
+int getImageSize (Camera *cam);
+bool setImageSize (Camera *cam, int size);
+bool getMotionDetect (Camera *cam);
+byte getMotionStatus(Camera *cam, byte x);
+bool motionDetected (Camera *cam);
+bool setMotionDetect (bool flag);
+bool setMotionStatus (byte x, byte d1, byte d2);
+byte getCompression (Camera *cam);
+bool setCompression(Camera *cam, byte c);
+bool getPTZ(Camera *cam, uint16_t *w, uint16_t *h, uint16_t *wz, uint16_t *hz, uint16_t *pan, uint16_t *tilt);
+bool setPTZ(Camera *cam, uint16_t wz, uint16_t hz, uint16_t pan, uint16_t tilt);