/** * @brief Write data to specific register in Camera Module OV7670 * @param Address: address of register * Value: value of data to be written into register * @retval ERROR, SUCCESS */ ErrorStatus Camera_WriteReg(uint8_t Address, uint8_t Value) { // Create start condition on SCCB/I2C interface SCCB_Start(); // Write data (Address of slave device for Write) on SCCB/I2C interface if((SCCB_Write(WriteAddress)) == Error) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(ERROR); // Return error and cancel the communication } Delay_us(100); // Write data (Address of register in Camera Module)on SCCB/I2C interface if((SCCB_Write(Address)) == Error) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(ERROR); // Return error and cancel the communication } // Write data (Data to write into register in Camera Module)on SCCB/I2C interface if((SCCB_Write(Value)) == Error) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(ERROR); // Return error and cancel the communication } // Create stop condition on SCCB/I2C interface SCCB_Stop(); return(SUCCESS); }
//读OV7660寄存器 u8 OV_ReadReg(u8 regID, u8 *regDat) { //通过写操作设置寄存器地址 SCCB_Start(); if(SCCB_Write(0x42))//写地址 { SCCB_Stop();//发送SCCB 总线停止传输命令 return 1;//错误返回 } delay_us(10); if(SCCB_Write(regID))//积存器ID { SCCB_Stop();//发送SCCB 总线停止传输命令 return 2;//错误返回 } SCCB_Stop();//发送SCCB 总线停止传输命令 delay_us(10); //设置寄存器地址后,才是读 SCCB_Start(); if(SCCB_Write(0x43))//读地址 { SCCB_Stop();//发送SCCB 总线停止传输命令 return 3;//错误返回 } delay_us(10); *regDat=SCCB_Read();//返回读到的值 noAck();//发送NACK命令 SCCB_Stop();//发送SCCB 总线停止传输命令 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 */ com7 = (SCCB_Read(sensor->slv_addr, REG_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 */ SCCB_Write(sensor->slv_addr, REG_COM1, com1); SCCB_Write(sensor->slv_addr, REG_COM7, com7); return 0; }
static int set_colorbar(sensor_t *sensor, int enable) { uint8_t ret = 0; // Read register scaling_xsc uint8_t reg = SCCB_Read(sensor->slv_addr, SCALING_XSC); // Pattern to set color bar bit[0]=0 in every case reg = SCALING_XSC_CBAR(reg); // Write pattern to SCALING_XSC ret = SCCB_Write(sensor->slv_addr, SCALING_XSC, reg); // Read register scaling_ysc uint8_t reg = SCCB_Read(sensor->slv_addr, SCALING_YSC); // Pattern to set color bar bit[0]=0 in every case reg = SCALING_YSC_CBAR(reg,enable); // Write pattern to SCALING_YSC ret = ret | SCCB_Write(sensor->slv_addr, SCALING_YSC, reg); // Set mirror on/off to pass self-tests // Read register MVFP uint8_t reg = SCCB_Read(sensor->slv_addr, MVFP); // Set mirror on/off reg = MVFP_SET_MIRROR(reg, enable); // Write back register MVFP ret = ret | SCCB_Write(sensor->slv_addr, MVFP, reg); // return 0 or 0xFF return ret; }
static int set_saturation(struct sensor_dev *sensor, int level) { int ret=0; level += (NUM_SATURATION_LEVELS / 2 ); if (level < 0 || level >= NUM_SATURATION_LEVELS) { return -1; } ret |= SCCB_Write(sensor->slv_addr, USAT, saturation_regs[level][0]); ret |= SCCB_Write(sensor->slv_addr, VSAT, saturation_regs[level][1]); return ret; }
static int set_brightness(struct sensor_dev *sensor, int level) { int ret=0; level += (NUM_BRIGHTNESS_LEVELS / 2); if (level < 0 || level >= NUM_BRIGHTNESS_LEVELS) { return -1; } ret |= SCCB_Write(sensor->slv_addr, BRIGHTNESS, brightness_regs[level][0]); ret |= SCCB_Write(sensor->slv_addr, SIGN_BIT, brightness_regs[level][1]); return ret; }
/** * @brief Read data form specific register in Camera Module OV7670 * @param Address: address of register in Camera Module * @retval ReturnState.Data -> Return read data from register * ReturnState.State -> Return state of the transmission */ ReturnState *Camera_ReadReg(uint8_t Address) { ReturnState returnState; // Structure for return Data and State (Success/Error) returnState.Data = 0x00; returnState.State = ERROR; // Create start condition on SCCB/I2C interface SCCB_Start(); // Write data (Address of slave device for Write) on SCCB/I2C interface if(Error == (SCCB_Write(WriteAddress))) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(&returnState); // Return error and cancel the communication } Delay_us(100); // Write data (Address of register in Camera Module)on SCCB/I2C interface if(Error == (SCCB_Write(Address))) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(&returnState); // Return error and cancel the communication } // Create stop condition on SCCB/I2C interface SCCB_Stop(); // Delay for SCCB/I2C Delay_us(100); // Create start condition on SCCB/I2C interface SCCB_Start(); // Write data (Address of slave device for Read) on SCCB/I2C interface if(Error == (SCCB_Write(ReadAddress))) { SCCB_Stop(); // Create stop condition on SCCB/I2C interface return(&returnState); // Return error and cancel the communication } Delay_us(500); // Received data from Camera Module (SCCB/I2C) returnState.Data = SCCB_Read(); // No acknowlage on SCCB/I2C interface NoAck(); // Create stop condition on SCCB/I2C interface SCCB_Stop(); // If everything is done correct return success returnState.State = SUCCESS; return(&returnState); }
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) { int ret=0; // Read register COM7 uint8_t reg = SCCB_Read(sensor->slv_addr, COM7); switch (pixformat) { case PIXFORMAT_RGB565: reg = COM7_SET_FMT(reg, COM7_FMT_RGB); break; case PIXFORMAT_YUV422: case PIXFORMAT_GRAYSCALE: reg = COM7_SET_FMT(reg, COM7_FMT_YUV); break; default: return -1; } // Write back register COM7 ret = SCCB_Write(sensor->slv_addr, COM7, reg); // Delay systick_sleep(30); 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++) { SCCB_Write(sensor->slv_addr, regs[0][i], regs[level][i]); } return 0; }
static int reset(struct sensor_dev *sensor) { int i=0; const uint8_t (*regs)[2]; // Reset all registers SCCB_Write(sensor->slv_addr, COM7, COM7_RESET); // Delay 10 ms systick_sleep(10); // Write default regsiters for (i=0, regs = default_regs; regs[i][0]; i++) { SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); } return 0; }
static int reset(sensor_t *sensor) { int i=0; const uint8_t (*regs)[2]=default_regs; /* Reset all registers */ SCCB_Write(sensor->slv_addr, REG_COM7, 0x80); /* delay n ms */ systick_sleep(10); /* Write initial regsiters */ while (regs[i][0]) { SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } return 0; }
static int set_whitebal(sensor_t *sensor, int enable) { uint8_t val; val = SCCB_Read(sensor->slv_addr, REG_COM8); SCCB_Write(sensor->slv_addr, REG_COM8, enable ? (val | REG_COM8_AWB) : (val & ~REG_COM8_AWB)); return 0; }
static int set_hmirror(sensor_t *sensor, int enable) { uint8_t val; val = SCCB_Read(sensor->slv_addr, REG_MVFP); SCCB_Write(sensor->slv_addr, REG_MVFP, enable ? (val | REG_MVFP_HMIRROR) : (val & ~REG_MVFP_HMIRROR)); return 0; }
static int set_special_effect(struct sensor_dev *sensor, enum sensor_sde sde) { int ret=0; switch (sde) { case SDE_NEGATIVE: ret |= SCCB_Write(sensor->slv_addr, SDE, 0x46); break; case SDE_NORMAL: ret |= SCCB_Write(sensor->slv_addr, SDE, 0x06); ret |= SCCB_Write(sensor->slv_addr, UFIX, 0x80); ret |= SCCB_Write(sensor->slv_addr, UFIX, 0x80); break; default: return -1; } return 0; }
static int set_vflip(sensor_t *sensor, int enable) { uint8_t val; val = SCCB_Read(sensor->slv_addr, REG_MVFP); SCCB_Write(sensor->slv_addr, REG_MVFP, enable ? (val | REG_MVFP_VFLIP) : (val & ~REG_MVFP_VFLIP)); return 0; }
static int set_gainceiling(struct sensor_dev *sensor, enum sensor_gainceiling gainceiling) { // Read register COM9 uint8_t reg = SCCB_Read(sensor->slv_addr, COM9); // Set gain ceiling reg = COM9_SET_AGC(reg, gainceiling); // Write back register COM9 return SCCB_Write(sensor->slv_addr, COM9, reg); }
static int set_hmirror(sensor_t *sensor, int enable) { // Read register MVFP uint8_t reg = SCCB_Read(sensor->slv_addr, MVFP); // Set mirror on/off reg = MVFP_SET_MIRROR(reg, enable); // Write back register COM3 return SCCB_Write(sensor->slv_addr, MVFP, reg); }
static int set_exposure_ctrl(sensor_t *sensor, int enable) { // Read register COM8 uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); // Set white bal on/off reg = COM8_SET_AEC(reg, enable); // Write back register COM8 return SCCB_Write(sensor->slv_addr, COM8, reg); }
static int set_vflip(sensor_t *sensor, int enable) { // Read register COM3 uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); // Set mirror on/off reg = COM3_SET_FLIP(reg, enable); // Write back register COM3 return SCCB_Write(sensor->slv_addr, COM3, reg); }
static int set_contrast(struct sensor_dev *sensor, int level) { int ret=0; level += (NUM_CONTRAST_LEVELS / 2); if (level < 0 || level >= NUM_CONTRAST_LEVELS) { return -1; } ret |= SCCB_Write(sensor->slv_addr, CONTRAST, contrast_regs[level][0]); return ret; }
static int set_colorbar(struct sensor_dev *sensor, int enable) { // Read register COM3 uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); // Set color bar on/off reg = COM3_SET_CBAR(reg, enable); // Set mirror on/off to pass self-tests reg = COM3_SET_MIRROR(reg, enable); // Write back register COM3 return SCCB_Write(sensor->slv_addr, COM3, reg); }
static int set_framesize(struct sensor_dev *sensor, enum sensor_framesize framesize) { int ret=0; uint16_t w = resolution[framesize][0]; uint16_t h = resolution[framesize][1]; // Write MSBs ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2); ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1); // Write LSBs ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2))); return ret; }
//写OV7670寄存器 u8 OV_WriteReg(u8 regID, u8 regDat) { SCCB_Start();//发送SCCB 总线开始传输命令 if(SCCB_Write(0x42))//写地址 { SCCB_Stop();//发送SCCB 总线停止传输命令 return 1;//错误返回 } delay_us(10); if(SCCB_Write(regID))//寄存器ID { SCCB_Stop();//发送SCCB 总线停止传输命令 return 2;//错误返回 } delay_us(10); if(SCCB_Write(regDat))//写数据到积存器 { SCCB_Stop();//发送SCCB 总线停止传输命令 return 3;//错误返回 } SCCB_Stop();//发送SCCB 总线停止传输命令 return 0;//成功返回 }
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 */ com7 = SCCB_Read(sensor->slv_addr, REG_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 */ SCCB_Write(sensor->slv_addr, REG_COM7, com7); /* Write pixel format registers */ while (regs[i][0]) { SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); i++; } return 0; }
static int set_exposure(sensor_t *sensor, int exposure) { uint8_t val; val = SCCB_Read(sensor->slv_addr, REG_COM1); /* exposure [1:0] */ SCCB_Write(sensor->slv_addr, REG_COM1, val | (exposure&0x03)); /* exposure [9:2] */ SCCB_Write(sensor->slv_addr, REG_AECH, ((exposure>>2)&0xFF)); /* exposure [15:10] */ SCCB_Write(sensor->slv_addr, REG_AECHM, ((exposure>>10)&0x3F)); return 0; }
static int set_framesize(sensor_t *sensor, framesize_t framesize) { int ret=0; uint16_t w = resolution[framesize][0]; uint16_t h = resolution[framesize][1]; // Write MSBs ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2); ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1); // Write LSBs ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2))); // Delay systick_sleep(30); return ret; }
static int set_pixformat(struct sensor_dev *sensor, enum sensor_pixformat pixformat) { // Read register COM7 uint8_t reg = SCCB_Read(sensor->slv_addr, COM7); switch (pixformat) { case PIXFORMAT_RGB565: reg = COM7_SET_FMT(reg, COM7_FMT_RGB); break; case PIXFORMAT_YUV422: case PIXFORMAT_GRAYSCALE: reg = COM7_SET_FMT(reg, COM7_FMT_YUV); break; default: return -1; } // Write back register COM7 return SCCB_Write(sensor->slv_addr, COM7, reg); }
static int set_gainceiling(sensor_t *sensor, gainceiling_t gainceiling) { /* Write gain ceiling register */ SCCB_Write(sensor->slv_addr, REG_COM9, (gainceiling<<4)); return 0; }
static int set_framerate(sensor_t *sensor, framerate_t framerate) { /* Write framerate register */ SCCB_Write(sensor->slv_addr, REG_CLKRC, framerate); return 0; }
static int set_gainceiling(enum sensor_gainceiling gainceiling) { /* Write gain ceiling register */ SCCB_Write(REG_COM9, (gainceiling<<4)); return 0; }