diff options
Diffstat (limited to 'fw/fe310/eos/dev/drv/arducam.c')
-rw-r--r-- | fw/fe310/eos/dev/drv/arducam.c | 99 |
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); +} |