static int reset(sensor_t *sensor) { mp_printf(&mp_plat_print, "[MAIXPY]: %s | sensor->slv_addr = %x\n",__func__,sensor->slv_addr); int i=0; const uint8_t (*regs)[2]; /* Reset all registers */ cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); cambus_writeb(sensor->slv_addr, COM7, COM7_SRST); /* delay n ms */ mp_hal_delay_ms(10); i = 0; regs = ov2640_default;//default_regs,ov2640_default /* Write initial regsiters */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } i = 0; regs = svga_config;//svga_regs,svga_config /* Write DSP input regsiters */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } return 0; }
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_gainceiling(sensor_t *sensor, gainceiling_t gainceiling) { int ret =0; /* Switch to SENSOR register bank */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); /* Write gain ceiling register */ ret |= cambus_writeb(sensor->slv_addr, COM9, COM9_AGC_SET(gainceiling)); return ret; }
static int set_quality(sensor_t *sensor, int qs) { int ret=0; /* Switch to DSP register bank */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); /* Write QS register */ ret |= cambus_writeb(sensor->slv_addr, QS, qs); return ret; }
static int set_brightness(sensor_t *sensor, int level) { int i; static uint8_t regs[NUM_BR_LEVELS + 1][3] = { { REG_AEW, REG_AEB, REG_VPT }, { 0x1c, 0x12, 0x50 }, /* -3 */ { 0x3d, 0x30, 0x71 }, /* -2 */ { 0x50, 0x44, 0x92 }, /* -1 */ { 0x70, 0x64, 0xc3 }, /* 0 */ { 0x90, 0x84, 0xd4 }, /* +1 */ { 0xc4, 0xbf, 0xf9 }, /* +2 */ { 0xd8, 0xd0, 0xfa }, /* +3 */ }; level += (NUM_BR_LEVELS / 2 + 1); if (level < 0 || level > NUM_BR_LEVELS) { return -1; } for (i=0; i<3; i++) { cambus_writeb(sensor->slv_addr, regs[0][i], regs[level][i]); } 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, 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_framesize(sensor_t *sensor, framesize_t framesize) { int ret=0; uint8_t clkrc; uint16_t w = resolution[framesize][0]; uint16_t h = resolution[framesize][1]; int i=0; const uint8_t (*regs)[2]; if ((w <= 800) && (h <= 600)) { clkrc =0x80; regs = svga_config; // regs = ov2640_config; } else { clkrc =0x81; regs = uxga_regs; } /* Disable DSP */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); ret |= cambus_writeb(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_BYPAS); /* Set CLKRC */ if(clkrc == 0x81) { ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR); ret |= cambus_writeb(sensor->slv_addr, CLKRC, clkrc); } /* Write DSP input regsiters */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } /* Write output width */ ret |= cambus_writeb(sensor->slv_addr,0xe0,0x04 ); /* OUTH[8]/OUTW[9:8] */ ret |= cambus_writeb(sensor->slv_addr, ZMOW, (w>>2)&0xFF); /* OUTW[7:0] (real/4) */ ret |= cambus_writeb(sensor->slv_addr, ZMOH, (h>>2)&0xFF); /* OUTH[7:0] (real/4) */ ret |= cambus_writeb(sensor->slv_addr, ZMHH, ((h>>8)&0x04)|((w>>10)&0x03)); /* OUTH[8]/OUTW[9:8] */ ret |= cambus_writeb(sensor->slv_addr,0xe0,0x00 ); /* OUTH[8]/OUTW[9:8] */ /* Enable DSP */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); ret |= cambus_writeb(sensor->slv_addr, R_BYPASS, R_BYPASS_DSP_EN); /* delay n ms */ mp_hal_delay_ms(30); dvp_set_image_size(w, h); return ret; }
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 reset(sensor_t *sensor) { int i=0; const uint8_t (*regs)[2]=default_regs; /* Reset all registers */ cambus_writeb(sensor->slv_addr, REG_COM7, 0x80); /* delay n ms */ systick_sleep(10); /* Write initial regsiters */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } return 0; }
static int set_saturation(sensor_t *sensor, int level) { int ret=0; level += (NUM_SATURATION_LEVELS / 2 + 1); if (level < 0 || level > NUM_SATURATION_LEVELS) { return -1; } /* Switch to DSP register bank */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); /* Write contrast registers */ for (int i=0; i<sizeof(saturation_regs[0])/sizeof(saturation_regs[0][0]); i++) { ret |= cambus_writeb(sensor->slv_addr, saturation_regs[0][i], saturation_regs[level][i]); } return ret; }
static int set_brightness(sensor_t *sensor, int level) { int ret=0; level += (NUM_BRIGHTNESS_LEVELS / 2 + 1); if (level < 0 || level > NUM_BRIGHTNESS_LEVELS) { return -1; } /* Switch to DSP register bank */ ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP); /* Write brightness registers */ for (int i=0; i<sizeof(brightness_regs[0])/sizeof(brightness_regs[0][0]); i++) { ret |= cambus_writeb(sensor->slv_addr, brightness_regs[0][i], brightness_regs[level][i]); } return 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; }
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) { int i=0; const uint8_t (*regs)[2]=NULL; /* read pixel format reg */ switch (pixformat) { case PIXFORMAT_RGB565: regs = rgb565_regs; break; case PIXFORMAT_YUV422: case PIXFORMAT_GRAYSCALE: regs = yuv422_regs; break; case PIXFORMAT_JPEG: regs = jpeg_regs; break; default: return -1; } /* Write initial regsiters */ while (regs[i][0]) { cambus_writeb(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } switch (pixformat) { case PIXFORMAT_RGB565: dvp_set_image_format(DVP_CFG_RGB_FORMAT); break; case PIXFORMAT_YUV422: dvp_set_image_format(DVP_CFG_YUV_FORMAT); break; case PIXFORMAT_GRAYSCALE: dvp_set_image_format(DVP_CFG_Y_FORMAT); break; case PIXFORMAT_JPEG: dvp_set_image_format(DVP_CFG_RGB_FORMAT); break; default: return -1; } /* delay n ms */ mp_hal_delay_ms(30); return 0; }
static int write_reg(sensor_t *sensor, uint8_t reg_addr, uint8_t reg_data) { return cambus_writeb(sensor->slv_addr, reg_addr, reg_data); }
static int set_framerate(sensor_t *sensor, framerate_t framerate) { /* Write framerate register */ cambus_writeb(sensor->slv_addr, REG_CLKRC, framerate); return 0; }
static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling) { /* Write gain ceiling register */ cambus_writeb(sensor->slv_addr, REG_COM9, (gainceiling<<4)); return 0; }