static int set_framesize(sensor_t *sensor, framesize_t framesize) { uint8_t com7=0; /* framesize/RGB */ uint8_t com1=0; /* Skip option */ /* read COM7 RGB bit */ cambus_readb(sensor->slv_addr, REG_COM7, &com7); com7 &= REG_COM7_RGB; switch (framesize) { case FRAMESIZE_QQCIF: com7 |= REG_COM7_QCIF; com1 |= REG_COM1_QQCIF|REG_COM1_SKIP2; break; case FRAMESIZE_QQVGA: com7 |= REG_COM7_QVGA; com1 |= REG_COM1_QQVGA|REG_COM1_SKIP2; break; case FRAMESIZE_QCIF: com7 |= REG_COM7_QCIF; break; default: return -1; } /* write the frame size registers */ cambus_writeb(sensor->slv_addr, REG_COM1, com1); cambus_writeb(sensor->slv_addr, REG_COM7, com7); return 0; }
static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling) { uint8_t reg; int ret = cambus_readb(sensor->slv_addr, BANK_SEL, ®); ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg | BANK_SEL_SENSOR); ret |= cambus_readb(sensor->slv_addr, COM8, ®); ret |= cambus_writeb(sensor->slv_addr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0)); if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) { float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 1.0); int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0))); int gain_hi = 0xF >> (4 - gain_temp); int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15); ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0)); } else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
static int read_reg(sensor_t *sensor, uint8_t reg_addr) { uint8_t reg_data; if (cambus_readb(sensor->slv_addr, reg_addr, ®_data) != 0) { return -1; } return reg_data; }
static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling) { uint8_t reg; int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®); ret |= cambus_writeb(sensor->slv_addr, REG_COM8, (reg & (~REG_COM8_AGC)) | ((enable != 0) ? REG_COM8_AGC : 0)); if ((enable == 0) && (!isnanf(gain_db)) && (!isinf(gain_db))) { float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 128.0), 1.0); int gain_temp = fast_roundf(fast_log2(IM_MAX(gain / 2.0, 1.0))); int gain_hi = 0x3F >> (6 - gain_temp); int gain_lo = IM_MIN(fast_roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15); ret |= cambus_writeb(sensor->slv_addr, REG_GAIN, ((gain_hi & 0x0F) << 4) | (gain_lo << 0)); ret |= cambus_readb(sensor->slv_addr, REG_VREF, ®); ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F)); } else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinf(gain_db_ceiling))) {
static int set_colorbar(sensor_t *sensor, int enable) { uint8_t reg; /* Switch to SENSOR register bank */ int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); /* Update COM7 */ ret |= cambus_readb(sensor->slv_addr, COM7, ®); if (enable) { reg |= COM7_COLOR_BAR; } else { reg &= ~COM7_COLOR_BAR; } return cambus_writeb(sensor->slv_addr, COM7, reg) | ret; }
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) { int i=0; const uint8_t (*regs)[2]; uint8_t com7=0; /* framesize/RGB */ /* read pixel format reg */ cambus_readb(sensor->slv_addr, REG_COM7, &com7); switch (pixformat) { case PIXFORMAT_RGB565: com7 |= REG_COM7_RGB; regs = rgb565_regs; break; case PIXFORMAT_YUV422: com7 &= (~REG_COM7_RGB); regs = yuv422_regs; break; case PIXFORMAT_GRAYSCALE: com7 &= (~REG_COM7_RGB); regs = yuv422_regs; break; default: return -1; } /* Set pixel format */ cambus_writeb(sensor->slv_addr, REG_COM7, com7); /* Write pixel format registers */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } return 0; }