Add (not really working) camera interface
This commit is contained in:
		
							parent
							
								
									8247add832
								
							
						
					
					
						commit
						116ab5d23b
					
				
					 7 changed files with 374 additions and 14 deletions
				
			
		
							
								
								
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -11,7 +11,8 @@
 | 
				
			||||||
        "stm32f100xb.h": "c",
 | 
					        "stm32f100xb.h": "c",
 | 
				
			||||||
        "buildid.h": "c",
 | 
					        "buildid.h": "c",
 | 
				
			||||||
        "font_arpegius_32.h": "c",
 | 
					        "font_arpegius_32.h": "c",
 | 
				
			||||||
        "font_arpegius_16.h": "c"
 | 
					        "font_arpegius_16.h": "c",
 | 
				
			||||||
 | 
					        "debug.h": "c"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "C_Cpp.intelliSenseEngineFallback": "Enabled"
 | 
					    "C_Cpp.intelliSenseEngineFallback": "Enabled"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
323
 | 
					405
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								src/main.c
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								src/main.c
									
										
									
									
									
								
							| 
						 | 
					@ -2,9 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(void)
 | 
					int main(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    LTP1245_Init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // LTP1245_FeedPaper(10);
 | 
					 | 
				
			||||||
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
 | 
					    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GPIOC->CRH = (GPIOC->CRH
 | 
					    GPIOC->CRH = (GPIOC->CRH
 | 
				
			||||||
| 
						 | 
					@ -12,16 +9,24 @@ int main(void)
 | 
				
			||||||
        | (0x01 << (4 * PIN_LED - 32))      // Output, max. 10 MHz
 | 
					        | (0x01 << (4 * PIN_LED - 32))      // Output, max. 10 MHz
 | 
				
			||||||
        ;
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char buff[30];
 | 
					    Camera_Init();
 | 
				
			||||||
    itoa(BUILD_NUMBER, buff, 10);
 | 
					    LTP1245_Init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char buff[30] = "Build No. ";
 | 
				
			||||||
 | 
					    itoa(BUILD_NUMBER, buff + strlen(buff), 10);
 | 
				
			||||||
    Print_Text(buff, &Messe_Duesseldorf_39);
 | 
					    Print_Text(buff, &Messe_Duesseldorf_39);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // LTP1245_FeedPaper(10);
 | 
					    LTP1245_FeedPaper(2);
 | 
				
			||||||
    // Print_Text("Testy McTestFace", &Arpegius_32);
 | 
					
 | 
				
			||||||
    // Print_Text("123555bcD", &Messe_Duesseldorf_39);
 | 
					    strcpy(buff, "Line count: ");
 | 
				
			||||||
    Print_Text("This is a long line with very much text!", &Hannover_Messe_Serif_26);
 | 
					    extern int LineCount;
 | 
				
			||||||
 | 
					    itoa(LineCount, buff + strlen(buff), 10);
 | 
				
			||||||
 | 
					    Print_Text(buff, &Hannover_Messe_Serif_26);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    LTP1245_FeedPaper(10);
 | 
					    LTP1245_FeedPaper(10);
 | 
				
			||||||
    LTP1245_Cut();
 | 
					    // LTP1245_FeedPaper(10);
 | 
				
			||||||
 | 
					    // LTP1245_Cut();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(;;)
 | 
					    for(;;)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
#include "pinning.h"
 | 
					#include "pinning.h"
 | 
				
			||||||
#include "buildid.h"
 | 
					#include "buildid.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "ov7670.h"
 | 
				
			||||||
#include "ltp1245.h"
 | 
					#include "ltp1245.h"
 | 
				
			||||||
#include "print.h"
 | 
					#include "print.h"
 | 
				
			||||||
#include "font_hannover_messe_serif_26.h"
 | 
					#include "font_hannover_messe_serif_26.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										347
									
								
								src/ov7670.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								src/ov7670.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,347 @@
 | 
				
			||||||
 | 
					#include "ov7670.h"
 | 
				
			||||||
 | 
					#include "pinning.h"
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define REG_GAIN                0x00
 | 
				
			||||||
 | 
					#define REG_BLUE                0x01
 | 
				
			||||||
 | 
					#define REG_RED                 0x02
 | 
				
			||||||
 | 
					#define REG_VREF                0x03
 | 
				
			||||||
 | 
					#define REG_COM1                0x04
 | 
				
			||||||
 | 
					#define REG_BAVE                0x05
 | 
				
			||||||
 | 
					#define REG_GbAVE               0x06
 | 
				
			||||||
 | 
					#define REG_AECHH               0x07
 | 
				
			||||||
 | 
					#define REG_RAVE                0x08
 | 
				
			||||||
 | 
					#define REV_COM2                0x09
 | 
				
			||||||
 | 
					#define REG_PID                 0x0a
 | 
				
			||||||
 | 
					#define REG_VER                 0x0b
 | 
				
			||||||
 | 
					#define REG_COM3                0x0c
 | 
				
			||||||
 | 
					#define REG_COM4                0x0d
 | 
				
			||||||
 | 
					#define REG_COM5                0x0e
 | 
				
			||||||
 | 
					#define REG_COM6                0x0f
 | 
				
			||||||
 | 
					#define REG_AECH                0x10
 | 
				
			||||||
 | 
					#define REG_CLKRC               0x11
 | 
				
			||||||
 | 
					#define REG_COM7                0x12
 | 
				
			||||||
 | 
					#define REG_COM8                0x13
 | 
				
			||||||
 | 
					#define REG_COM9                0x14
 | 
				
			||||||
 | 
					#define REG_COM10               0x15
 | 
				
			||||||
 | 
					#define REG_HSTART              0x17
 | 
				
			||||||
 | 
					#define REG_HSTOP               0x18
 | 
				
			||||||
 | 
					#define REG_VSTRT               0x19
 | 
				
			||||||
 | 
					#define REG_VSTOP               0x1a
 | 
				
			||||||
 | 
					#define REG_PSHIFT              0x1b
 | 
				
			||||||
 | 
					#define REG_MIDH                0x1c
 | 
				
			||||||
 | 
					#define REG_MIDL                0x1d
 | 
				
			||||||
 | 
					#define REG_MVFP                0x1e
 | 
				
			||||||
 | 
					#define REG_LAEC                0x1f
 | 
				
			||||||
 | 
					#define REG_ADCCTR0             0x20
 | 
				
			||||||
 | 
					#define REG_ADCCTR1             0x21
 | 
				
			||||||
 | 
					#define REG_ADCCTR2             0x22
 | 
				
			||||||
 | 
					#define REG_ADCCTR3             0x23
 | 
				
			||||||
 | 
					#define REG_AEW                 0x24
 | 
				
			||||||
 | 
					#define REG_AEB                 0x25
 | 
				
			||||||
 | 
					#define REG_VPT                 0x26
 | 
				
			||||||
 | 
					#define REG_BBIAS               0x27
 | 
				
			||||||
 | 
					#define REG_GbBIAS              0x28
 | 
				
			||||||
 | 
					#define REG_EXHCH               0x2a
 | 
				
			||||||
 | 
					#define REG_EXHCL               0x2b
 | 
				
			||||||
 | 
					#define REG_RBIAS               0x2c
 | 
				
			||||||
 | 
					#define REG_ADVFL               0x2d
 | 
				
			||||||
 | 
					#define REG_ADVFH               0x2e
 | 
				
			||||||
 | 
					#define REG_YAVE                0x2f
 | 
				
			||||||
 | 
					#define REG_HSYST               0x30
 | 
				
			||||||
 | 
					#define REG_HSYEN               0x31
 | 
				
			||||||
 | 
					#define REG_HREF                0x32
 | 
				
			||||||
 | 
					#define REG_CHLF                0x33
 | 
				
			||||||
 | 
					#define REG_ARBLM               0x34
 | 
				
			||||||
 | 
					#define REG_ADC                 0x37
 | 
				
			||||||
 | 
					#define REG_ACOM                0x38
 | 
				
			||||||
 | 
					#define REG_OFON                0x39
 | 
				
			||||||
 | 
					#define REG_TSLB                0x3a
 | 
				
			||||||
 | 
					#define REG_COM11               0x3b
 | 
				
			||||||
 | 
					#define REG_COM12               0x3c
 | 
				
			||||||
 | 
					#define REG_COM13               0x3d
 | 
				
			||||||
 | 
					#define REG_COM14               0x3e
 | 
				
			||||||
 | 
					#define REG_EDGE                0x3f
 | 
				
			||||||
 | 
					#define REG_COM15               0x40
 | 
				
			||||||
 | 
					#define REG_COM16               0x41
 | 
				
			||||||
 | 
					#define REG_COM17               0x42
 | 
				
			||||||
 | 
					#define REG_REG4B               0x4b
 | 
				
			||||||
 | 
					#define REG_DNSTH               0x4c
 | 
				
			||||||
 | 
					#define REG_MTX1                0x4f
 | 
				
			||||||
 | 
					#define REG_MTX2                0x50
 | 
				
			||||||
 | 
					#define REG_MTX3                0x51
 | 
				
			||||||
 | 
					#define REG_MTX4                0x52
 | 
				
			||||||
 | 
					#define REG_MTX5                0x53
 | 
				
			||||||
 | 
					#define REG_MTX6                0x54
 | 
				
			||||||
 | 
					#define REG_BRIGHT              0x55
 | 
				
			||||||
 | 
					#define REG_CONTRAS             0x56
 | 
				
			||||||
 | 
					#define REG_CONTRAS_CENTER      0x57
 | 
				
			||||||
 | 
					#define REG_MTXS                0x58
 | 
				
			||||||
 | 
					#define REG_LCC1                0x62
 | 
				
			||||||
 | 
					#define REG_LCC2                0x63
 | 
				
			||||||
 | 
					#define REG_LCC3                0x64
 | 
				
			||||||
 | 
					#define REG_LCC4                0x65
 | 
				
			||||||
 | 
					#define REG_LCC5                0x66
 | 
				
			||||||
 | 
					#define REG_MANU                0x67
 | 
				
			||||||
 | 
					#define REG_MANV                0x68
 | 
				
			||||||
 | 
					#define REG_GFIX                0x69
 | 
				
			||||||
 | 
					#define REG_GGAIN               0x6a
 | 
				
			||||||
 | 
					#define REG_DBLV                0x6b
 | 
				
			||||||
 | 
					#define REG_AWBCTR3             0x6c
 | 
				
			||||||
 | 
					#define REG_AWBCTR2             0x6d
 | 
				
			||||||
 | 
					#define REG_AWBCTR1             0x6e
 | 
				
			||||||
 | 
					#define REG_AWBCTR0             0x6f
 | 
				
			||||||
 | 
					#define REG_SCALING_XSC         0x70
 | 
				
			||||||
 | 
					#define REG_SCALING_YSC         0x71
 | 
				
			||||||
 | 
					#define REG_SCALING_DCWCTR      0x72
 | 
				
			||||||
 | 
					#define REG_SCALING_PCLK_DIV    0x73
 | 
				
			||||||
 | 
					#define REG_REG74               0x74
 | 
				
			||||||
 | 
					#define REG_REG75               0x75
 | 
				
			||||||
 | 
					#define REG_REG76               0x76
 | 
				
			||||||
 | 
					#define REG_REG77               0x77
 | 
				
			||||||
 | 
					#define REG_SLOP                0x7a
 | 
				
			||||||
 | 
					#define REG_GAM1                0x7b
 | 
				
			||||||
 | 
					#define REG_GAM2                0x7c
 | 
				
			||||||
 | 
					#define REG_GAM3                0x7d
 | 
				
			||||||
 | 
					#define REG_GAM4                0x7e
 | 
				
			||||||
 | 
					#define REG_GAM5                0x7f
 | 
				
			||||||
 | 
					#define REG_GAM6                0x80
 | 
				
			||||||
 | 
					#define REG_GAM7                0x81
 | 
				
			||||||
 | 
					#define REG_GAM8                0x82
 | 
				
			||||||
 | 
					#define REG_GAM9                0x83
 | 
				
			||||||
 | 
					#define REG_GAM10               0x84
 | 
				
			||||||
 | 
					#define REG_GAM11               0x85
 | 
				
			||||||
 | 
					#define REG_GAM12               0x86
 | 
				
			||||||
 | 
					#define REG_GAM13               0x87
 | 
				
			||||||
 | 
					#define REG_GAM14               0x88
 | 
				
			||||||
 | 
					#define REG_GAM15               0x89
 | 
				
			||||||
 | 
					#define REG_RGB444              0x8c
 | 
				
			||||||
 | 
					#define REG_DM_LNL              0x92
 | 
				
			||||||
 | 
					#define REG_DM_LNH              0x93
 | 
				
			||||||
 | 
					#define REG_LCC6                0x94
 | 
				
			||||||
 | 
					#define REG_LCC7                0x95
 | 
				
			||||||
 | 
					#define REG_BD50ST              0x9d
 | 
				
			||||||
 | 
					#define REG_BD60ST              0x9e
 | 
				
			||||||
 | 
					#define REG_HAECC1              0x9f
 | 
				
			||||||
 | 
					#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_BD60MAX             0xab
 | 
				
			||||||
 | 
					#define REG_STR_OPT             0xac
 | 
				
			||||||
 | 
					#define REG_STR_R               0xad
 | 
				
			||||||
 | 
					#define REG_STR_G               0xae
 | 
				
			||||||
 | 
					#define REG_STR_B               0xaf
 | 
				
			||||||
 | 
					#define REG_ABLC1               0xb1
 | 
				
			||||||
 | 
					#define REG_THL_ST              0xb3
 | 
				
			||||||
 | 
					#define REG_THL_DLT             0xb5
 | 
				
			||||||
 | 
					#define REG_AD_CHB              0xbe
 | 
				
			||||||
 | 
					#define REG_AD_CHR              0xbf
 | 
				
			||||||
 | 
					#define REG_AD_CHGb             0xc0
 | 
				
			||||||
 | 
					#define REG_AD_CHGr             0xc1
 | 
				
			||||||
 | 
					#define REG_SATCR               0xc9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define I2C_ADDRESS             0x42
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t ImageBuffer[176 * 144 / 8];
 | 
				
			||||||
 | 
					static volatile int CurrentLine = 0;
 | 
				
			||||||
 | 
					uint8_t LineBuffer1[176];
 | 
				
			||||||
 | 
					uint8_t LineBuffer2[176];
 | 
				
			||||||
 | 
					int LineCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t ReadRegister(uint8_t reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while(I2C1->SR2 & I2C_SR2_BUSY);
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_START;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_SB);
 | 
				
			||||||
 | 
					    I2C1->DR = I2C_ADDRESS;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_ADDR);
 | 
				
			||||||
 | 
					    I2C1->SR2;       // Dummy read
 | 
				
			||||||
 | 
					    I2C1->DR = reg;  // Write the register number to be read
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF));
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_STOP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read the register value
 | 
				
			||||||
 | 
					    while(I2C1->SR2 & I2C_SR2_BUSY);
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_START;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_SB);
 | 
				
			||||||
 | 
					    I2C1->DR = I2C_ADDRESS | 1;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_ADDR);
 | 
				
			||||||
 | 
					    I2C1->SR2;       // Dummy read
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_STOP;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_RXNE);
 | 
				
			||||||
 | 
					    uint8_t data = I2C1->DR;
 | 
				
			||||||
 | 
					    return data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void WriteRegister(uint8_t reg, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    while(I2C1->SR2 & I2C_SR2_BUSY);
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_START;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_SB);
 | 
				
			||||||
 | 
					    I2C1->DR = I2C_ADDRESS;
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & I2C_SR1_ADDR);
 | 
				
			||||||
 | 
					    I2C1->SR2;          // Dummy read
 | 
				
			||||||
 | 
					    I2C1->DR = reg;     // Write the register number
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF));
 | 
				
			||||||
 | 
					    I2C1->DR = value;   // Write the register value
 | 
				
			||||||
 | 
					    while(~I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF));
 | 
				
			||||||
 | 
					    I2C1->CR1 |= I2C_CR1_STOP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Camera_Init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
 | 
				
			||||||
 | 
					    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
 | 
				
			||||||
 | 
					    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
 | 
				
			||||||
 | 
					    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
 | 
				
			||||||
 | 
					    RCC->AHBENR |= RCC_AHBENR_DMA1EN;
 | 
				
			||||||
 | 
					    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
 | 
				
			||||||
 | 
					    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reset pin
 | 
				
			||||||
 | 
					    GPIOB->CRH = (GPIOB->CRH
 | 
				
			||||||
 | 
					        & ~(0x0f << (4 * PIN_CAMERA_RESET - 32)))
 | 
				
			||||||
 | 
					        | (0x01 << (4 * PIN_CAMERA_RESET - 32))     // Output, max. 10 MHz
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					    GPIOB->BRR = (1 << PIN_CAMERA_RESET);
 | 
				
			||||||
 | 
					    GPIOB->BSRR = (1 << PIN_CAMERA_RESET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Enable MCO for camera main clock line (PLL / 2 -> 24 MHz)
 | 
				
			||||||
 | 
					    RCC->CFGR |= RCC_CFGR_MCO;
 | 
				
			||||||
 | 
					    GPIOA->CRH = (GPIOA->CRH
 | 
				
			||||||
 | 
					        & ~(0x0f << (4 * PIN_CAMERA_MCLK - 32)))
 | 
				
			||||||
 | 
					        | (0x0b << (4 * PIN_CAMERA_MCLK - 32))      // Output, max. 50 MHz
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // I2C interface for camera configuration
 | 
				
			||||||
 | 
					    GPIOB->CRH = (GPIOB->CRH
 | 
				
			||||||
 | 
					        & ~(0x0f << (4 * PIN_CAMERA_SCL - 32))
 | 
				
			||||||
 | 
					        & ~(0x0f << (4 * PIN_CAMERA_SDA - 32)))
 | 
				
			||||||
 | 
					        | (0x0e << (4 * PIN_CAMERA_SCL - 32))       // AF OD output, 2 MHz
 | 
				
			||||||
 | 
					        | (0x0e << (4 * PIN_CAMERA_SDA - 32))       // AF OD output, 2 MHz
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    I2C1->CR1 = I2C_CR1_SWRST;
 | 
				
			||||||
 | 
					    I2C1->CR1 = 0;
 | 
				
			||||||
 | 
					    I2C1->CR2 = (24 << I2C_CR2_FREQ_Pos);
 | 
				
			||||||
 | 
					    I2C1->CCR = I2C_CCR_FS | I2C_CCR_DUTY | (1 << I2C_CCR_CCR_Pos) | 5;
 | 
				
			||||||
 | 
					    I2C1->CR1 = I2C_CR1_PE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Timer setup
 | 
				
			||||||
 | 
					    AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP_PARTIALREMAP;
 | 
				
			||||||
 | 
					    GPIOB->CRL = (GPIOB->CRL
 | 
				
			||||||
 | 
					        & ~(0x0f << (PIN_CAMERA_HSYNC * 4))
 | 
				
			||||||
 | 
					        & ~(0x0f << (PIN_CAMERA_PCLK * 4)))
 | 
				
			||||||
 | 
					        | (0x04 << (PIN_CAMERA_HSYNC * 4))          // Floating input
 | 
				
			||||||
 | 
					        | (0x04 << (PIN_CAMERA_PCLK * 4))           // Floating input
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					    GPIOA->CRH = (GPIOA->CRH
 | 
				
			||||||
 | 
					        & ~(0x0f << (PIN_CAMERA_VSYNC * 4 - 32)))
 | 
				
			||||||
 | 
					        | (0x04 << (PIN_CAMERA_VSYNC * 4 - 32))     // Floating input
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TIM1_CH2 is VSYNC
 | 
				
			||||||
 | 
					    TIM1->PSC = 0;
 | 
				
			||||||
 | 
					    TIM1->ARR = 65535;
 | 
				
			||||||
 | 
					    TIM1->CCMR1 = TIM_CCMR1_CC2S_0;
 | 
				
			||||||
 | 
					    TIM1->CCER = TIM_CCER_CC2E;
 | 
				
			||||||
 | 
					    TIM1->DIER = TIM_DIER_CC2IE;
 | 
				
			||||||
 | 
					    TIM1->CR1 = TIM_CR1_CEN;
 | 
				
			||||||
 | 
					    NVIC_SetPriority(TIM1_CC_IRQn, 0);
 | 
				
			||||||
 | 
					    NVIC_EnableIRQ(TIM1_CC_IRQn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TIM3_CH2 is HSYNC and should trigger an interrupt, while TIM3_CH1 is the
 | 
				
			||||||
 | 
					    // pixel clock and should trigger DMA transfers
 | 
				
			||||||
 | 
					    TIM3->PSC = 0;
 | 
				
			||||||
 | 
					    TIM3->ARR = 1;
 | 
				
			||||||
 | 
					    TIM3->CCMR1 = TIM_CCMR1_CC2S_0 | TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1PSC_0;
 | 
				
			||||||
 | 
					    TIM3->CCER = TIM_CCER_CC2P | TIM_CCER_CC2E | TIM_CCER_CC1E | TIM_CCER_CC1P;
 | 
				
			||||||
 | 
					    TIM3->DIER = TIM_DIER_CC2IE;
 | 
				
			||||||
 | 
					    TIM3->CR1 = TIM_CR1_CEN;
 | 
				
			||||||
 | 
					    NVIC_SetPriority(TIM3_IRQn, 0);
 | 
				
			||||||
 | 
					    NVIC_EnableIRQ(TIM3_IRQn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fetch GPIOA IDR lower byte
 | 
				
			||||||
 | 
					    DMA1_Channel6->CMAR = (uint32_t)&(GPIOA->IDR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Startup delay
 | 
				
			||||||
 | 
					    for(volatile int i = 0; i < 1000; i++);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Camera configuration
 | 
				
			||||||
 | 
					    ReadRegister(REG_PID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Disable timing resets
 | 
				
			||||||
 | 
					    WriteRegister(REG_COM6, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Enable scaling
 | 
				
			||||||
 | 
					    WriteRegister(REG_COM3, 0x08 | 0x04);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Use QCIF output format
 | 
				
			||||||
 | 
					    WriteRegister(REG_COM7, 0x08);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Blank pixel clock during sync pulses
 | 
				
			||||||
 | 
					    WriteRegister(REG_COM10, 0x20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set clock prescaler to 2
 | 
				
			||||||
 | 
					    WriteRegister(REG_CLKRC, 0x4 | 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Enable pixel clock scaling
 | 
				
			||||||
 | 
					    WriteRegister(REG_COM14, 0x10);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TIM1_CC_IRQHandler(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // VSYNC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // GPIOC->BRR = (1 << PIN_LED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LineCount = CurrentLine;
 | 
				
			||||||
 | 
					    CurrentLine = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Dummy read
 | 
				
			||||||
 | 
					    TIM1->CCR2;
 | 
				
			||||||
 | 
					    TIM1->SR &= ~TIM_SR_CC2IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // GPIOC->BSRR = (1 << PIN_LED);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TIM3_IRQHandler(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // HSYNC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPIOC->BRR = (1 << PIN_LED);
 | 
				
			||||||
 | 
					    TIM3->DIER &= ~TIM_DIER_CC1DE;
 | 
				
			||||||
 | 
					    TIM3->SR &= ~TIM_SR_CC1IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DMA1_Channel6->CCR = 0;
 | 
				
			||||||
 | 
					    DMA1_Channel6->CNDTR = sizeof(LineBuffer1);
 | 
				
			||||||
 | 
					    if(CurrentLine & 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DMA1_Channel6->CMAR = (uint32_t)LineBuffer1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DMA1_Channel6->CMAR = (uint32_t)LineBuffer2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    DMA1_Channel6->CCR = DMA_CCR_PL | DMA_CCR_MINC | DMA_CCR_EN;
 | 
				
			||||||
 | 
					    TIM3->DIER |= TIM_DIER_CC1DE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ImageBuffer[0] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CurrentLine++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Dummy read
 | 
				
			||||||
 | 
					    TIM3->CCR2;
 | 
				
			||||||
 | 
					    TIM3->SR &= ~TIM_SR_CC2IF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPIOC->BSRR = (1 << PIN_LED);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/ov7670.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/ov7670.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include "stm32f1xx.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Camera_Init(void);
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@
 | 
				
			||||||
#define PIN_CAMERA_DB6          6   // PA6  - Camera data line 6
 | 
					#define PIN_CAMERA_DB6          6   // PA6  - Camera data line 6
 | 
				
			||||||
#define PIN_CAMERA_DB7          7   // PA7  - Camera data line 7
 | 
					#define PIN_CAMERA_DB7          7   // PA7  - Camera data line 7
 | 
				
			||||||
#define PIN_CAMERA_MCLK         8   // PA8  - Camera main clock (MCO/TIM1_CH1)
 | 
					#define PIN_CAMERA_MCLK         8   // PA8  - Camera main clock (MCO/TIM1_CH1)
 | 
				
			||||||
#define PIN_CAMERA_PCLK         9   // PA9  - Camera pixel clock (TIM1_CH2)
 | 
					#define PIN_CAMERA_VSYNC        9   // PA9  - Camera VSYNC (TIM1_CH2)
 | 
				
			||||||
#define PIN_STEPPER_AP          10  // PA10 - Stepper phase A positive
 | 
					#define PIN_STEPPER_AP          10  // PA10 - Stepper phase A positive
 | 
				
			||||||
#define PIN_STEPPER_BP          11  // PA11 - Stepper phase B positive
 | 
					#define PIN_STEPPER_BP          11  // PA11 - Stepper phase B positive
 | 
				
			||||||
#define PIN_STEPPER_AM          12  // PA12 - Stepper phase A negative
 | 
					#define PIN_STEPPER_AM          12  // PA12 - Stepper phase A negative
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@
 | 
				
			||||||
#define PIN_VBATT               1   // PB1  - Battery monitor (ADC12_IN9)
 | 
					#define PIN_VBATT               1   // PB1  - Battery monitor (ADC12_IN9)
 | 
				
			||||||
#define PIN_SUPPLY              2   // PB2  - Voltage regulator enable
 | 
					#define PIN_SUPPLY              2   // PB2  - Voltage regulator enable
 | 
				
			||||||
#define PIN_PAPER               3   // PB3  - Paper detect
 | 
					#define PIN_PAPER               3   // PB3  - Paper detect
 | 
				
			||||||
#define PIN_CAMERA_VSYNC        4   // PB4  - Camera VSYNC (TIM3_CH1)
 | 
					#define PIN_CAMERA_PCLK         4   // PB4  - Camera pixel clock (TIM3_CH1)
 | 
				
			||||||
#define PIN_CAMERA_HSYNC        5   // PB5  - Camera VSYNC (TIM3_CH2)
 | 
					#define PIN_CAMERA_HSYNC        5   // PB5  - Camera VSYNC (TIM3_CH2)
 | 
				
			||||||
#define PIN_HEAD                6   // PB6  - Head up sensor
 | 
					#define PIN_HEAD                6   // PB6  - Head up sensor
 | 
				
			||||||
#define PIN_PAPER_CUT           7   // PB7  - Paper cutter servo (TIM4_CH2)
 | 
					#define PIN_PAPER_CUT           7   // PB7  - Paper cutter servo (TIM4_CH2)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue