Compare commits
No commits in common. "dc61ac7f85e6f3788bce240f6a1a7f89fea02184" and "d6932ae70cfe81516c261fb888f55f716ed063fc" have entirely different histories.
dc61ac7f85
...
d6932ae70c
|
@ -1 +1 @@
|
||||||
615
|
562
|
||||||
|
|
21
src/config.h
21
src/config.h
|
@ -1,21 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Use 2D Floyd-Steinberg dithering. Uncomment to use simple line-wise
|
|
||||||
// dithering.
|
|
||||||
#define CONFIG_USE_2D_DITHERING
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
// Print number of black pixels per captured frame
|
|
||||||
// #define CONFIG_PRINT_EXPOSURE_DEBUG_INFORMATION
|
|
18
src/main.c
18
src/main.c
|
@ -22,24 +22,6 @@ int main(void)
|
||||||
extern uint8_t ImageBuffer[CAMERA_IMAGE_WIDTH * CAMERA_IMAGE_HEIGHT / 8];
|
extern uint8_t ImageBuffer[CAMERA_IMAGE_WIDTH * CAMERA_IMAGE_HEIGHT / 8];
|
||||||
Print_Image(ImageBuffer, CAMERA_IMAGE_WIDTH, CAMERA_IMAGE_HEIGHT, 2);
|
Print_Image(ImageBuffer, CAMERA_IMAGE_WIDTH, CAMERA_IMAGE_HEIGHT, 2);
|
||||||
|
|
||||||
#ifdef CONFIG_PRINT_EXPOSURE_DEBUG_INFORMATION
|
|
||||||
char buffer[32] = "Finished after lines: ";
|
|
||||||
itoa(Camera_FinalFrameCount, buffer + strlen(buffer), 10);
|
|
||||||
|
|
||||||
Print_Text(buffer, &Arpegius_32);
|
|
||||||
Print_Text("Black pixel counts:", &Arpegius_32);
|
|
||||||
for(int i = 0; i < Camera_FinalFrameCount; i++)
|
|
||||||
{
|
|
||||||
if(i >= (int)(sizeof(Camera_BlackPixelCounts)
|
|
||||||
/ sizeof(Camera_BlackPixelCounts[0])))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
itoa(Camera_BlackPixelCounts[i], buffer, 10);
|
|
||||||
Print_Text(buffer, &Arpegius_32);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LTP1245_FeedPaper(100);
|
LTP1245_FeedPaper(100);
|
||||||
|
|
||||||
BMP_Save(ImageBuffer, CAMERA_IMAGE_WIDTH, CAMERA_IMAGE_HEIGHT);
|
BMP_Save(ImageBuffer, CAMERA_IMAGE_WIDTH, CAMERA_IMAGE_HEIGHT);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "font_arpegius_16.h"
|
#include "font_arpegius_16.h"
|
||||||
#include "font_arpegius_32.h"
|
#include "font_arpegius_32.h"
|
||||||
#include "bmp.h"
|
#include "bmp.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
int main(void);
|
int main(void);
|
||||||
|
|
||||||
|
|
61
src/ov7670.c
61
src/ov7670.c
|
@ -126,12 +126,12 @@
|
||||||
#define REG_HAECC2 0xa0
|
#define REG_HAECC2 0xa0
|
||||||
#define REG_SCALING_PCLK_DELAY 0xa2
|
#define REG_SCALING_PCLK_DELAY 0xa2
|
||||||
#define REG_NT_CTRL 0xa4
|
#define REG_NT_CTRL 0xa4
|
||||||
#define REG_AECGMAX 0xa5
|
#define REG_BD50MAX 0xa5
|
||||||
#define REG_LPH 0xa6
|
#define REG_HAECC3 0xa6
|
||||||
#define REG_UPL 0xa7
|
#define REG_HAECC4 0xa7
|
||||||
#define REG_TPL 0xa8
|
#define REG_HAECC5 0xa8
|
||||||
#define REG_TPH 0xa9
|
#define REG_HAECC6 0xa9
|
||||||
#define REG_NALG 0xaa
|
#define REG_HAECC7 0xaa
|
||||||
#define REG_BD60MAX 0xab
|
#define REG_BD60MAX 0xab
|
||||||
#define REG_STR_OPT 0xac
|
#define REG_STR_OPT 0xac
|
||||||
#define REG_STR_R 0xad
|
#define REG_STR_R 0xad
|
||||||
|
@ -156,13 +156,10 @@ static volatile int FrameCount = 0;
|
||||||
volatile int Camera_Captured = 0;
|
volatile int Camera_Captured = 0;
|
||||||
static unsigned int BlackPixels = 0;
|
static unsigned int BlackPixels = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_USE_EXPOSURE_CORRECTION
|
#ifdef CAMERA_USE_EXPOSURE_CORRECTION
|
||||||
static volatile int ExposureCorrection = 0;
|
static volatile int ExposureCorrection = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile unsigned int Camera_BlackPixelCounts[] = {0};
|
|
||||||
volatile int Camera_FinalFrameCount = -1;
|
|
||||||
|
|
||||||
static uint8_t ReadRegister(uint8_t reg)
|
static uint8_t ReadRegister(uint8_t reg)
|
||||||
{
|
{
|
||||||
while(I2C1->SR2 & I2C_SR2_BUSY);
|
while(I2C1->SR2 & I2C_SR2_BUSY);
|
||||||
|
@ -304,24 +301,6 @@ void Camera_Init(void)
|
||||||
WriteRegister(REG_COM14, 0x18 | 1);
|
WriteRegister(REG_COM14, 0x18 | 1);
|
||||||
WriteRegister(REG_SCALING_PCLK_DIV, 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.
|
// Enable VSYNC interrupts. TIM3 is enabled at the first VSYNC.
|
||||||
FrameCount = 0;
|
FrameCount = 0;
|
||||||
Camera_Captured = 0;
|
Camera_Captured = 0;
|
||||||
|
@ -348,34 +327,20 @@ void TIM1_CC_IRQHandler(void)
|
||||||
CurrentLine = 0;
|
CurrentLine = 0;
|
||||||
FrameCount++;
|
FrameCount++;
|
||||||
|
|
||||||
#ifdef CONFIG_USE_EXPOSURE_CORRECTION
|
#ifdef CAMERA_USE_EXPOSURE_CORRECTION
|
||||||
// Correct exposure across frames
|
// Correct exposure across frames
|
||||||
ExposureCorrection += 32 * BlackPixels / CAMERA_PIXELS - 16;
|
ExposureCorrection += 32 * BlackPixels / CAMERA_PIXELS - 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if the last frame's exposure is reasonable
|
// Check if the last frame's exposure is reasonable
|
||||||
if(!Camera_Captured && FrameCount >= CONFIG_MIN_FRAMES
|
if(FrameCount >= 5)
|
||||||
&& (
|
|
||||||
(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_Captured = 1;
|
||||||
Camera_FinalFrameCount = FrameCount;
|
|
||||||
// Disable everything
|
// Disable everything
|
||||||
TIM3->CR1 = 0;
|
TIM3->CR1 = 0;
|
||||||
TIM1->CR1 = 0;
|
TIM1->CR1 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FrameCount < (int)(sizeof(Camera_BlackPixelCounts)
|
|
||||||
/ sizeof(Camera_BlackPixelCounts[0])))
|
|
||||||
{
|
|
||||||
Camera_BlackPixelCounts[FrameCount] = BlackPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset black pixel counter
|
// Reset black pixel counter
|
||||||
BlackPixels = 0;
|
BlackPixels = 0;
|
||||||
|
|
||||||
|
@ -396,7 +361,7 @@ void TIM3_IRQHandler(void)
|
||||||
DMA1_Channel6->CCR = DMA_CCR_PL | DMA_CCR_MINC | DMA_CCR_EN;
|
DMA1_Channel6->CCR = DMA_CCR_PL | DMA_CCR_MINC | DMA_CCR_EN;
|
||||||
TIM3->DIER |= TIM_DIER_CC1DE;
|
TIM3->DIER |= TIM_DIER_CC1DE;
|
||||||
|
|
||||||
#ifdef CONFIG_USE_2D_DITHERING
|
#ifdef CAMERA_USE_2D_DITHERING
|
||||||
static int8_t y_errors[CAMERA_IMAGE_WIDTH + 2] = {0};
|
static int8_t y_errors[CAMERA_IMAGE_WIDTH + 2] = {0};
|
||||||
|
|
||||||
if(CurrentLine == 0)
|
if(CurrentLine == 0)
|
||||||
|
@ -409,7 +374,7 @@ void TIM3_IRQHandler(void)
|
||||||
&& (CurrentLine / 2 < CAMERA_IMAGE_HEIGHT))
|
&& (CurrentLine / 2 < CAMERA_IMAGE_HEIGHT))
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef CONFIG_USE_2D_DITHERING
|
#ifdef CAMERA_USE_2D_DITHERING
|
||||||
// Apply errors propagated from the previous line. Since y_errors is
|
// Apply errors propagated from the previous line. Since y_errors is
|
||||||
// overwritten during x error diffusion, this is done now.
|
// overwritten during x error diffusion, this is done now.
|
||||||
for(int i = 0; i < CAMERA_IMAGE_WIDTH; i++)
|
for(int i = 0; i < CAMERA_IMAGE_WIDTH; i++)
|
||||||
|
@ -423,7 +388,7 @@ void TIM3_IRQHandler(void)
|
||||||
for(int i = 0; i < CAMERA_IMAGE_WIDTH; i++)
|
for(int i = 0; i < CAMERA_IMAGE_WIDTH; i++)
|
||||||
{
|
{
|
||||||
int pixel = LineBuffer[i + 15] + x_error;
|
int pixel = LineBuffer[i + 15] + x_error;
|
||||||
#ifdef CONFIG_USE_EXPOSURE_CORRECTION
|
#ifdef CAMERA_USE_EXPOSURE_CORRECTION
|
||||||
if(ExposureCorrection < 0)
|
if(ExposureCorrection < 0)
|
||||||
{
|
{
|
||||||
if(pixel < -ExposureCorrection)
|
if(pixel < -ExposureCorrection)
|
||||||
|
@ -456,7 +421,7 @@ void TIM3_IRQHandler(void)
|
||||||
~(0x80 >> (i % 8));
|
~(0x80 >> (i % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_USE_2D_DITHERING
|
#ifdef CAMERA_USE_2D_DITHERING
|
||||||
// Error propagated to the next pixel in the same line
|
// Error propagated to the next pixel in the same line
|
||||||
x_error = error * 7 / 16;
|
x_error = error * 7 / 16;
|
||||||
|
|
||||||
|
|
11
src/ov7670.h
11
src/ov7670.h
|
@ -2,16 +2,19 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "stm32f1xx.h"
|
#include "stm32f1xx.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#define CAMERA_IMAGE_WIDTH 160
|
#define CAMERA_IMAGE_WIDTH 160
|
||||||
#define CAMERA_IMAGE_HEIGHT 144
|
#define CAMERA_IMAGE_HEIGHT 144
|
||||||
#define CAMERA_PIXELS (CAMERA_IMAGE_WIDTH * CAMERA_IMAGE_HEIGHT)
|
#define CAMERA_PIXELS (CAMERA_IMAGE_WIDTH * CAMERA_IMAGE_HEIGHT)
|
||||||
|
|
||||||
|
// Use 2D Floyd-Steinberg dithering. Uncomment to use simple line-wise
|
||||||
|
// dithering.
|
||||||
|
#define CAMERA_USE_2D_DITHERING
|
||||||
|
|
||||||
|
// Use a primitive autoexposure by shifting each frames luminosity based on the
|
||||||
|
// ratio of white to black pixels in the previous frames
|
||||||
|
// #define CAMERA_USE_EXPOSURE_CORRECTION
|
||||||
|
|
||||||
extern volatile int Camera_Captured;
|
extern volatile int Camera_Captured;
|
||||||
|
|
||||||
extern volatile unsigned int Camera_BlackPixelCounts[CONFIG_MAX_FRAMES];
|
|
||||||
extern volatile int Camera_FinalFrameCount;
|
|
||||||
|
|
||||||
void Camera_Init(void);
|
void Camera_Init(void);
|
Loading…
Reference in a new issue