diff --git a/build-number.txt b/build-number.txt index 02a6b26..3bfc51a 100644 --- a/build-number.txt +++ b/build-number.txt @@ -1 +1 @@ -641 +562 diff --git a/photo.jpg b/photo.jpg index 29f18b9..0f0ad92 100644 Binary files a/photo.jpg and b/photo.jpg differ diff --git a/src/bmp.c b/src/bmp.c index 5524ae0..0603975 100644 --- a/src/bmp.c +++ b/src/bmp.c @@ -64,7 +64,7 @@ void BMP_ConstructFilename(int number, char *buffer, unsigned int size) memcpy(buffer + size - 5, ".BMP", 5); } -int BMP_Save(uint8_t *data, int width, int height) +void BMP_Save(uint8_t *data, int width, int height) { FATFS fs; FIL fp; @@ -74,19 +74,19 @@ int BMP_Save(uint8_t *data, int width, int height) rc = f_mount(&fs, "", 0); if(rc) { - return -1; + return; } int file_number = BMP_PickFileNumber(); if(file_number == -1) - return -2; + return; char filename[13]; BMP_ConstructFilename(file_number, filename, sizeof(filename)); rc = f_open(&fp, filename, FA_WRITE | FA_CREATE_NEW); if(rc) { - return -3; + return; } // Rows must be padded to a multiple of 4 bytes @@ -121,26 +121,24 @@ int BMP_Save(uint8_t *data, int width, int height) }; if(f_write(&fp, &file_header, sizeof(file_header), &bw) != FR_OK) - return -4; + return; if(f_write(&fp, &core_header, sizeof(core_header), &bw) != FR_OK) - return -4; + return; if(f_write(&fp, &colour_table, sizeof(colour_table), &bw) != FR_OK) - return -4; + return; // BMPs are stored with their rows from the bottom upwards for(int y = height - 1; y >= 0; y--) { uint8_t *row = data + y * (width / 8); if(f_write(&fp, row, width / 8, &bw) != FR_OK) - return -4; + return; if(padding_length != 0) { if(f_write(&fp, padding_bytes, padding_length, &bw) != FR_OK) - return -4; + return; } } f_close(&fp); - - return file_number; } diff --git a/src/bmp.h b/src/bmp.h index 758db22..117d3aa 100644 --- a/src/bmp.h +++ b/src/bmp.h @@ -4,4 +4,4 @@ #include #include -int BMP_Save(uint8_t *data, int width, int height); +void BMP_Save(uint8_t *data, int width, int height); diff --git a/src/config.h b/src/config.h deleted file mode 100644 index 2e255fb..0000000 --- a/src/config.h +++ /dev/null @@ -1,24 +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 - -// Print file number if a file was saved to SD card -#define CONFIG_PRINT_FILE_NUMBER \ No newline at end of file diff --git a/src/main.c b/src/main.c index cdffd8f..2085066 100644 --- a/src/main.c +++ b/src/main.c @@ -14,48 +14,18 @@ int main(void) Camera_Init(); LTP1245_Init(); - LTP1245_FeedPaper(50); + LTP1245_FeedPaper(100); + LTP1245_FeedPaper(10); while(!Camera_Captured); extern uint8_t ImageBuffer[CAMERA_IMAGE_WIDTH * CAMERA_IMAGE_HEIGHT / 8]; 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); + LTP1245_FeedPaper(100); - Print_Text(buffer, &Hannover_Messe_Serif_26, Print_LeftAligned); - Print_Text("Black pixel counts:", &Hannover_Messe_Serif_26, - Print_LeftAligned); - 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, &Hannover_Messe_Serif_26, Print_LeftAligned); - } -#endif - - int file_number = BMP_Save(ImageBuffer, CAMERA_IMAGE_WIDTH, - CAMERA_IMAGE_HEIGHT); - (void)file_number; - -#ifdef CONFIG_PRINT_FILE_NUMBER - LTP1245_FeedPaper(10); - char buffer[32] = "- "; - if(file_number >= 0) - { - itoa(file_number, buffer + strlen(buffer), 10); - strcpy(buffer + strlen(buffer), " -"); - Print_Text(buffer, &Hannover_Messe_Serif_26, Print_Centred); - } -#endif + BMP_Save(ImageBuffer, CAMERA_IMAGE_WIDTH, CAMERA_IMAGE_HEIGHT); - LTP1245_FeedPaper(80); LTP1245_FeedPaper(10); GPIOC->BRR = (1 << PIN_SUPPLY); diff --git a/src/main.h b/src/main.h index 532c2d3..fd56361 100644 --- a/src/main.h +++ b/src/main.h @@ -16,7 +16,6 @@ #include "font_arpegius_16.h" #include "font_arpegius_32.h" #include "bmp.h" -#include "config.h" int main(void); diff --git a/src/ov7670.c b/src/ov7670.c index 23c0c99..377c613 100644 --- a/src/ov7670.c +++ b/src/ov7670.c @@ -126,12 +126,12 @@ #define REG_HAECC2 0xa0 #define REG_SCALING_PCLK_DELAY 0xa2 #define REG_NT_CTRL 0xa4 -#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_BD50MAX 0xa5 +#define REG_HAECC3 0xa6 +#define REG_HAECC4 0xa7 +#define REG_HAECC5 0xa8 +#define REG_HAECC6 0xa9 +#define REG_HAECC7 0xaa #define REG_BD60MAX 0xab #define REG_STR_OPT 0xac #define REG_STR_R 0xad @@ -156,13 +156,10 @@ static volatile int FrameCount = 0; volatile int Camera_Captured = 0; static unsigned int BlackPixels = 0; -#ifdef CONFIG_USE_EXPOSURE_CORRECTION +#ifdef CAMERA_USE_EXPOSURE_CORRECTION 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); @@ -304,24 +301,6 @@ 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; @@ -348,34 +327,20 @@ void TIM1_CC_IRQHandler(void) CurrentLine = 0; FrameCount++; -#ifdef CONFIG_USE_EXPOSURE_CORRECTION +#ifdef CAMERA_USE_EXPOSURE_CORRECTION // Correct exposure across frames ExposureCorrection += 32 * BlackPixels / CAMERA_PIXELS - 16; #endif // Check if the last frame's exposure is reasonable - 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 - )) + if(FrameCount >= 5) { 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; @@ -396,7 +361,7 @@ void TIM3_IRQHandler(void) DMA1_Channel6->CCR = DMA_CCR_PL | DMA_CCR_MINC | DMA_CCR_EN; 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}; if(CurrentLine == 0) @@ -409,7 +374,7 @@ void TIM3_IRQHandler(void) && (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 // overwritten during x error diffusion, this is done now. 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++) { int pixel = LineBuffer[i + 15] + x_error; -#ifdef CONFIG_USE_EXPOSURE_CORRECTION +#ifdef CAMERA_USE_EXPOSURE_CORRECTION if(ExposureCorrection < 0) { if(pixel < -ExposureCorrection) @@ -456,7 +421,7 @@ void TIM3_IRQHandler(void) ~(0x80 >> (i % 8)); } -#ifdef CONFIG_USE_2D_DITHERING +#ifdef CAMERA_USE_2D_DITHERING // Error propagated to the next pixel in the same line x_error = error * 7 / 16; diff --git a/src/ov7670.h b/src/ov7670.h index 1f3666c..8ffa57d 100644 --- a/src/ov7670.h +++ b/src/ov7670.h @@ -2,16 +2,19 @@ #include #include "stm32f1xx.h" -#include "config.h" #define CAMERA_IMAGE_WIDTH 160 #define CAMERA_IMAGE_HEIGHT 144 #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 unsigned int Camera_BlackPixelCounts[CONFIG_MAX_FRAMES]; -extern volatile int Camera_FinalFrameCount; - void Camera_Init(void); \ No newline at end of file diff --git a/src/print.c b/src/print.c index 9147d05..82ad27a 100644 --- a/src/print.c +++ b/src/print.c @@ -3,45 +3,12 @@ static uint8_t Print_Buffer[PRINT_BUFFER_LINES * LTP1245_LINE_BYTES]; -int Print_MeasureTextWidth(const char *text, const Font_t *font) -{ - char c; - int width = 0; - while((c = *text++) != 0) - { - if(c > font->glyphcount + font->charoffset - || c < font->charoffset) - { - continue; - } - - width += font->glyphs[c - font->charoffset].width; - } - return width; -} - -void Print_Text(const char *text, const Font_t *font, - Print_TextAlignment_t alignment) +void Print_Text(const char *text, const Font_t *font) { int height = font->height; memset(Print_Buffer, 0, LTP1245_LINE_BYTES * height); char c; int xpos = 0; - if(alignment != Print_LeftAligned) - { - int width = Print_MeasureTextWidth(text, font); - if(width < LTP1245_LINEWIDTH) - { - if(alignment == Print_Centred) - { - xpos = LTP1245_LINEWIDTH / 2 - width / 2; - } - else - { - xpos = LTP1245_LINEWIDTH - width; - } - } - } while((c = *text++) != 0) { if(c > font->glyphcount + font->charoffset diff --git a/src/print.h b/src/print.h index d21b5f1..168594d 100644 --- a/src/print.h +++ b/src/print.h @@ -7,13 +7,5 @@ #define PRINT_BUFFER_LINES 64 -typedef enum -{ - Print_LeftAligned, - Print_Centred, - Print_RightAligned, -} Print_TextAlignment_t; - -void Print_Text(const char *text, const Font_t *font, - Print_TextAlignment_t alignment); +void Print_Text(const char *text, const Font_t *font); void Print_Image(const uint8_t *data, int width, int height, int scale); \ No newline at end of file