summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/dev/drv/arducam.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/dev/drv/arducam.c')
-rw-r--r--fw/fe310/eos/dev/drv/arducam.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/fw/fe310/eos/dev/drv/arducam.c b/fw/fe310/eos/dev/drv/arducam.c
new file mode 100644
index 0000000..e41d541
--- /dev/null
+++ b/fw/fe310/eos/dev/drv/arducam.c
@@ -0,0 +1,99 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "eos.h"
+
+#include "soc/spi.h"
+
+#include "arducam.h"
+
+#define ARDUCAM_REG_CAPTURE_CTRL 0x01
+#define ARDUCAM_REG_FIFO_CTRL 0x04
+
+#define ARDUCAM_REG_GPIO_DIR 0x05
+#define ARDUCAM_REG_GPIO_WR 0x06
+#define ARDUCAM_REG_GPIO_RD 0x45
+
+#define ARDUCAM_REG_STATUS 0x41
+
+#define ARDUCAM_REG_VER 0x40
+
+#define ARDUCAM_REG_READ_BURST 0x3c
+#define ARDUCAM_REG_READ_BYTE 0x3d
+
+#define ARDUCAM_REG_FIFO_SIZE1 0x42
+#define ARDUCAM_REG_FIFO_SIZE2 0x43
+#define ARDUCAM_REG_FIFO_SIZE3 0x44
+
+#define ARDUCAM_VAL_FIFO_CTRL_CLEAR 0x01
+#define ARDUCAM_VAL_FIFO_CTRL_START 0x02
+#define ARDUCAM_VAL_FIFO_CTRL_RSTWR 0x10
+#define ARDUCAM_VAL_FIFO_CTRL_RSTRD 0x20
+
+#define ARDUCAM_VAL_STATUS_VSYNC 0x01
+#define ARDUCAM_VAL_STATUS_SHUTTER 0x02
+#define ARDUCAM_VAL_STATUS_CPTDONE 0x08
+
+#define ARDUCAM_VAL_GPIO_RST 0x01
+#define ARDUCAM_VAL_GPIO_PWRDN 0x02
+#define ARDUCAM_VAL_GPIO_PWREN 0x04
+
+static uint8_t reg_read(uint8_t addr) {
+ uint8_t ret;
+
+ eos_spi_cs_set();
+ eos_spi_xchg8(addr, 0);
+ ret = eos_spi_xchg8(0, 0);
+ eos_spi_cs_clear();
+
+ return ret;
+}
+
+static void reg_write(uint8_t addr, uint8_t val) {
+ eos_spi_cs_set();
+ eos_spi_xchg8(addr | 0x80, 0);
+ eos_spi_xchg8(val, 0);
+ eos_spi_cs_clear();
+}
+
+void arducam_capture(void) {
+ reg_write(ARDUCAM_REG_FIFO_CTRL, ARDUCAM_VAL_FIFO_CTRL_START);
+}
+
+int arducam_capture_done(void) {
+ return !!(reg_read(ARDUCAM_REG_STATUS) & ARDUCAM_VAL_STATUS_CPTDONE);
+}
+
+void arducam_capture_wait(void) {
+ int done = 0;
+
+ while (!done) {
+ done = arducam_capture_done();
+ }
+}
+
+uint32_t arducam_fbuf_size(void) {
+ uint32_t ret;
+
+ ret = reg_read(ARDUCAM_REG_FIFO_SIZE1);
+ ret |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8;
+ ret |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16;
+ return ret;
+}
+
+void arducam_fbuf_read(uint8_t *buffer, uint16_t sz, int first) {
+ int i;
+
+ eos_spi_cs_set();
+ eos_spi_xchg8(ARDUCAM_REG_READ_BURST, 0);
+ if (first) eos_spi_xchg8(0, 0);
+
+ for (i=0; i<sz; i++) {
+ buffer[i] = eos_spi_xchg8(0, 0);
+ }
+ eos_spi_cs_clear();
+}
+
+void arducam_fbuf_done(void) {
+ reg_write(ARDUCAM_REG_FIFO_CTRL, ARDUCAM_VAL_FIFO_CTRL_CLEAR);
+}