diff --git a/src/config.h b/src/config.h index d7d5693..61e22c4 100644 --- a/src/config.h +++ b/src/config.h @@ -6,4 +6,13 @@ // Use a primitive autoexposure by shifting each frames luminosity based on the // ratio of white to black pixels in the previous frames -// #define CONFIG_USE_EXPOSURE_CORRECTION \ No newline at end of file +// #define CONFIG_USE_EXPOSURE_CORRECTION + +// Capture a frame when it is within this tolerance of 50% black pixels +#define CONFIG_TOLERANCE 0.2 + +// Wait this number of frames before a frame is eligible for beaing captured +#define CONFIG_MIN_FRAMES 2 + +// Maximum number of frames to wait. Capture even if it is not within tolerance. +#define CONFIG_MAX_FRAMES 15 \ No newline at end of file diff --git a/src/ov7670.c b/src/ov7670.c index b63e49f..23c0c99 100644 --- a/src/ov7670.c +++ b/src/ov7670.c @@ -1,7 +1,6 @@ #include "ov7670.h" #include "pinning.h" #include "debug.h" -#include "config.h" #define REG_GAIN 0x00 #define REG_BLUE 0x01 @@ -127,12 +126,12 @@ #define REG_HAECC2 0xa0 #define REG_SCALING_PCLK_DELAY 0xa2 #define REG_NT_CTRL 0xa4 -#define REG_BD50MAX 0xa5 -#define REG_HAECC3 0xa6 -#define REG_HAECC4 0xa7 -#define REG_HAECC5 0xa8 -#define REG_HAECC6 0xa9 -#define REG_HAECC7 0xaa +#define REG_AECGMAX 0xa5 +#define REG_LPH 0xa6 +#define REG_UPL 0xa7 +#define REG_TPL 0xa8 +#define REG_TPH 0xa9 +#define REG_NALG 0xaa #define REG_BD60MAX 0xab #define REG_STR_OPT 0xac #define REG_STR_R 0xad @@ -161,6 +160,9 @@ static unsigned int BlackPixels = 0; static volatile int ExposureCorrection = 0; #endif +volatile unsigned int Camera_BlackPixelCounts[] = {0}; +volatile int Camera_FinalFrameCount = -1; + static uint8_t ReadRegister(uint8_t reg) { while(I2C1->SR2 & I2C_SR2_BUSY); @@ -302,6 +304,24 @@ void Camera_Init(void) WriteRegister(REG_COM14, 0x18 | 1); WriteRegister(REG_SCALING_PCLK_DIV, 1); + // Set maximum gain ceiling + WriteRegister(REG_COM9, 0xca); + + // Disable auto-exposure, enable auto-gain + WriteRegister(REG_COM8, 0xec); + + // // Disable auto-gain, enable auto-exposure + // WriteRegister(REG_COM8, 0xe9); + + // Use histogram-based auto-exposure + WriteRegister(REG_NALG, 0x94); + + // Increase AEC speed: + // ‘Decrease TPL but not less than UPL [default 0xc1] and increase TPH but + // not bigger than LPH [default 0xf0]’ + WriteRegister(REG_TPL, 0xc1); + WriteRegister(REG_TPH, 0xf0); + // Enable VSYNC interrupts. TIM3 is enabled at the first VSYNC. FrameCount = 0; Camera_Captured = 0; @@ -334,14 +354,28 @@ void TIM1_CC_IRQHandler(void) #endif // Check if the last frame's exposure is reasonable - if(FrameCount >= 5) + if(!Camera_Captured && FrameCount >= CONFIG_MIN_FRAMES + && ( + (BlackPixels > (int)(CAMERA_PIXELS / 2 + - CAMERA_PIXELS * CONFIG_TOLERANCE) + && BlackPixels < (int)(CAMERA_PIXELS / 2 + + CAMERA_PIXELS * CONFIG_TOLERANCE)) + || FrameCount >= CONFIG_MAX_FRAMES + )) { Camera_Captured = 1; + Camera_FinalFrameCount = FrameCount; // Disable everything TIM3->CR1 = 0; TIM1->CR1 = 0; } + if(FrameCount < (int)(sizeof(Camera_BlackPixelCounts) + / sizeof(Camera_BlackPixelCounts[0]))) + { + Camera_BlackPixelCounts[FrameCount] = BlackPixels; + } + // Reset black pixel counter BlackPixels = 0; diff --git a/src/ov7670.h b/src/ov7670.h index 80f8f3b..1f3666c 100644 --- a/src/ov7670.h +++ b/src/ov7670.h @@ -2,6 +2,7 @@ #include #include "stm32f1xx.h" +#include "config.h" #define CAMERA_IMAGE_WIDTH 160 #define CAMERA_IMAGE_HEIGHT 144 @@ -10,4 +11,7 @@ extern volatile int Camera_Captured; +extern volatile unsigned int Camera_BlackPixelCounts[CONFIG_MAX_FRAMES]; +extern volatile int Camera_FinalFrameCount; + void Camera_Init(void); \ No newline at end of file