It's nucleo f4 DMA trandfer for ov7670&ILI9341.
Dependencies: mbed ILI9341_SPI OV7670_SCCB
Diff: main.cpp
- Revision:
- 0:ce10b2e08479
- Child:
- 2:de327fb4e2c5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Apr 04 02:05:59 2016 +0000 @@ -0,0 +1,750 @@ +#include "mbed.h" +#include "TIM_DMAInit.h" +#include "SPI_DMAInit.h" + +/* + + ********ov7670******** + +3V3 - 3V3 GND-GND + PC_12 - SIOC SIDO - PC10 + PD_2 - VSYNC HREF - A3 + B4,A4 - PCLK XCLK - PC_9 + PB_7 - D7 D6 - PB_6 + PB_5 - D5 D4 - PB_4 + PB_3 - D3 D2 - PB_2 + PB_1 - D1 D0 - PB_0 ++3V3-330Ω-RESET + + ********74HC00********* +A1 VCC - +5V +B1 B4 -- PCLK +Y1 A4 -- PCLK +A2 Y4 - B3 +B2 B3 - Y4 +Y2 A3 - HREF +GND Y3 - PA8 + + ********ILI9341********* +SDO - PA6 +LED - 100Ω - +5V +SCK - PA5 +SDI - PA7 +DC - PA_4 +RS - PA_12 +CS - PA_11 +GND - GND +VCC - +5V + + ********NUCLEOF401RE******* + +U5V× +E5V○ + +*/ + + + + + + +#define REG_COM1 0x04 /* Control 1 */ +#define REG_COM6 0x0f /* Control 6 */ +#define REG_AECH 0x10 /* More bits of AEC value */ +#define REG_CLKRC 0x11 /* Clocl control */ +#define CLK_EXT 0x40 /* Use external clock directly */ +#define CLK_SCALE 0x3f /* Mask for internal clock scale */ +#define REG_COM7 0x12 /* Control 7 */ +#define COM7_RESET 0x80 /* Register reset */ +#define COM7_FMT_MASK 0x38 +#define COM7_FMT_VGA 0x00 +#define COM7_FMT_CIF 0x20 /* CIF format */ +#define COM7_FMT_QVGA 0x10 /* QVGA format */ +#define COM7_FMT_QCIF 0x08 /* QCIF format */ +#define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */ +#define COM7_YUV 0x00 /* YUV */ +#define COM7_BAYER 0x01 /* Bayer format */ +#define COM7_PBAYER 0x05 /* "Processed bayer" */ +#define REG_COM8 0x13 /* Control 8 */ +#define REG_COM9 0x14 /* Control 9 - gain ceiling */ +#define REG_TSLB 0x3a /* lots of stuff */ +#define REG_COM15 0x40 /* Control 15 */ +#define COM15_R10F0 0x00 /* Data range 10 to F0 */ +#define COM15_R01FE 0x80 /* 01 to FE */ +#define COM15_R00FF 0xc0 /* 00 to FF */ +#define COM15_RGB565 0x10 /* RGB565 output */ +#define COM15_RGB555 0x30 /* RGB555 output */ +#define REG_COM16 0x41 /* Control 16 */ +#define COM16_AWBGAIN 0x08 /* AWB gain enable */ +#define REG_COM17 0x42 /* Control 17 */ +#define COM17_AECWIN 0xc0 /* AEC window - must match COM4 */ +#define COM17_CBAR 0x08 /* DSP Color bar */ +#define REG_CMATRIX_BASE 0x4f +#define CMATRIX_LEN 6 +#define REG_CMATRIX_SIGN 0x58 +#define REG_BRIGHT 0x55 /* Brightness */ +#define REG_CONTRAS 0x56 /* Contrast control */ + +#define REG_GFIX 0x69 /* Fix gain control */ + +#define REG_REG76 0x76 /* OV's name */ +#define R76_BLKPCOR 0x80 /* Black pixel correction enable */ +#define R76_WHTPCOR 0x40 /* White pixel correction enable */ + +#define REG_RGB444 0x8c /* RGB 444 control */ +#define R444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ +#define R444_RGBX 0x01 /* Empty nibble at end */ + +#define REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ +#define REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ + +#define REG_BD50MAX 0xa5 /* 50hz banding step limit */ +#define REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ +#define REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ +#define REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ +#define REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ +#define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ +#define REG_BD60MAX 0xab /* 60hz banding step limit */ + + + +uint8_t dma_buf[145][300]; +uint8_t flag_dma; + + + +InterruptIn VSYNC(PD_2); + +SPI spi(PA_7,PA_6,PA_5); + +DigitalOut dc(PA_4); +DigitalOut rs(PA_12); +DigitalOut cs(PA_11); + +DigitalInOut SDA(PC_10); +DigitalInOut SCL(PC_12); + +PortIn cdata(PortB, 0x00ff); + +void window (unsigned int x, unsigned int y, unsigned int w, unsigned int h); +void pixel(int x, int y, int color); +void vline(int x, int y0, int y1, int color); +void circle(int x0, int y0, int r, int color); +void fillcircle(int x0, int y0, int r, int color); +void fillrect(int x0, int y0, int x1, int y1, int color); +void wr_cmd(unsigned char cmd); +void wr_dat(unsigned char dat); +char rd_byte(unsigned char cmd); +int rd_32(unsigned char cmd); +int Read_ID(void); +void tft_reset(); +void fillrect(int x0, int y0, int x1, int y1, int color); + +void I2cstart(void); +void I2cstop(void); +void I2cout(unsigned char datar); +void c(unsigned char adrs,unsigned char datak); +void cam_init(); + +void camdma_start(); + +void test_color(); + + + + +int main() { + + + GPIO_InitTypeDef gpioconf1; + __GPIOB_CLK_ENABLE(); + gpioconf1.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |GPIO_PIN_14 | GPIO_PIN_15;//pa13 + gpioconf1.Mode = GPIO_MODE_INPUT; + gpioconf1.Pull = GPIO_PULLDOWN; + gpioconf1.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(GPIOB, &gpioconf1); + + + HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_HSE, RCC_MCODIV_1); + + GPIO_InitTypeDef GPIO_InitStruct; + /*Configure GPIO pin : PC9 MCO2 for cam XCLK*/ + __GPIOC_CLK_ENABLE(); + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + // spi_Init(); + dma_init(); + + spi.format(8,3); + spi.frequency(20000000); + tft_reset(); + + __disable_irq(); + + VSYNC.rise(&camdma_start);//PCLK割り込み + cam_init(); + +fillrect(0,0,150,290,0xf800);//red + + +wait(1); + wr_cmd(0x2C); + spi.write(0x66); + spi_Init(); + + __enable_irq(); + + + while(1) { + } +} + + + + +void wr_cmd(unsigned char cmd) +{ + dc = 0; + cs = 0; + spi.write(cmd); // mbed lib + dc = 1; +} +void wr_dat(unsigned char dat) +{ + spi.write(dat); // mbed lib +} +char rd_byte(unsigned char cmd) +{ + char r; + dc = 0; + cs = 0; + spi.write(cmd); // mbed lib + cs = 1; + r = spi.write(0xff); + cs = 1; + return(r); +} + +// read 32 bit +int rd_32(unsigned char cmd) +{ + int d; + char r; + dc = 0; + cs = 0; + d = cmd; + d = d << 1; + spi.format(9,3); // we have to add a dummy clock cycle + spi.write(d); + spi.format(8,3); + dc = 1; + r = spi.write(0xff); + d = r; + r = spi.write(0xff); + d = (d << 8) | r; + r = spi.write(0xff); + d = (d << 8) | r; + r = spi.write(0xff); + d = (d << 8) | r; + cs = 1; + return(d); +} + +int Read_ID(void){ + int r; + r = rd_byte(0x0A); + r = rd_byte(0x0A); + r = rd_byte(0x0A); + r = rd_byte(0x0A); + return(r); +} + + +// Init code based on MI0283QT datasheet + +void tft_reset() +{ + cs = 1; // cs high + dc = 1; // dc high + rs = 0; // display reset + + wait_us(50); + rs = 1; // end hardware reset + wait_ms(5); + + wr_cmd(0x01); // SW reset + wait_ms(5); + wr_cmd(0x28); // display off + + /* Start Initial Sequence ----------------------------------------------------*/ + wr_cmd(0xCF); + spi.write(0x00); + spi.write(0x83); + spi.write(0x30); + cs = 1; + + wr_cmd(0xED); + spi.write(0x64); + spi.write(0x03); + spi.write(0x12); + spi.write(0x81); + cs = 1; + + wr_cmd(0xE8); + spi.write(0x85); + spi.write(0x01); + spi.write(0x79); + cs = 1; + + wr_cmd(0xCB); + spi.write(0x39); + spi.write(0x2C); + spi.write(0x00); + spi.write(0x34); + spi.write(0x02); + cs = 1; + + wr_cmd(0xF7); + spi.write(0x20); + cs = 1; + + wr_cmd(0xEA); + spi.write(0x00); + spi.write(0x00); + cs = 1; + + wr_cmd(0xC0); // POWER_CONTROL_1 + spi.write(0x26); + cs = 1; + + wr_cmd(0xC1); // POWER_CONTROL_2 + spi.write(0x11); + cs = 1; + + wr_cmd(0xC5); // VCOM_CONTROL_1 + spi.write(0x35); + spi.write(0x3E); + cs = 1; + + wr_cmd(0xC7); // VCOM_CONTROL_2 + spi.write(0xBE); + cs = 1; + + wr_cmd(0x36); // MEMORY_ACCESS_CONTROL + spi.write(0x48); + cs = 1; + + wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET + spi.write(0x55); // 16 bit pixel + cs = 1; + + wr_cmd(0xB1); // Frame Rate + spi.write(0x00); + spi.write(0x1B); + cs = 1; + + wr_cmd(0xF2); // Gamma Function Disable + spi.write(0x08); + cs = 1; + + wr_cmd(0x26); + spi.write(0x01); // gamma set for curve 01/2/04/08 + cs = 1; + + wr_cmd(0xE0); // positive gamma correction + spi.write(0x1F); + spi.write(0x1A); + spi.write(0x18); + spi.write(0x0A); + spi.write(0x0F); + spi.write(0x06); + spi.write(0x45); + spi.write(0x87); + spi.write(0x32); + spi.write(0x0A); + spi.write(0x07); + spi.write(0x02); + spi.write(0x07); + spi.write(0x05); + spi.write(0x00); + cs = 1; + + wr_cmd(0xE1); // negativ gamma correction + spi.write(0x00); + spi.write(0x25); + spi.write(0x27); + spi.write(0x05); + spi.write(0x10); + spi.write(0x09); + spi.write(0x3A); + spi.write(0x78); + spi.write(0x4D); + spi.write(0x05); + spi.write(0x18); + spi.write(0x0D); + spi.write(0x38); + spi.write(0x3A); + spi.write(0x1F); + cs = 1; + + wr_cmd(0x2A); + spi.write(0); + spi.write(0); + spi.write(0); + spi.write(0x95); + + cs = 1; + wr_cmd(0x2B); + spi.write(0); + spi.write(0); + spi.write(0x00); + spi.write(0x90); + cs = 1; + + //wr_cmd(0x34); // tearing effect off + //_cs = 1; + + //wr_cmd(0x35); // tearing effect on + //_cs = 1; + + wr_cmd(0xB7); // entry mode + spi.write(0x07); + cs = 1; + + wr_cmd(0xB6); // display function control + spi.write(0x0A); + spi.write(0x82); + spi.write(0x27); + spi.write(0x00); + cs = 1; + + wr_cmd(0x11); // sleep out + cs = 1; + + wait_ms(100); + + wr_cmd(0x29); // display on + cs = 1; + + wait_ms(100); + + } + void pixel(int x, int y, int color) +{ + wr_cmd(0x2A); + spi.write(x >> 8); + spi.write(x); + cs = 1; + wr_cmd(0x2B); + spi.write(y >> 8); + spi.write(y); + cs = 1; + wr_cmd(0x2C); // send pixel + //#if defined TARGET_KL25Z // 8 Bit SPI + spi.write(color >> 8); + spi.write(color & 0xff); + /*#else + SPI::format(16,3); // switch to 16 bit Mode 3 + SPI::write(color); // Write D0..D15 + SPI::format(8,3); + #endif*/ + cs = 1; +} + +void window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) +{ + wr_cmd(0x2A); + spi.write(x >> 8); + spi.write(x); + spi.write((x+w-1) >> 8); + spi.write(x+w-1); + + cs = 1; + wr_cmd(0x2B); + spi.write(y >> 8); + spi.write(y); + spi.write((y+h-1) >> 8); + spi.write(y+h-1); + cs = 1; +} + +void vline(int x, int y0, int y1, int color) +{ + int h; + h = y1 - y0 + 1; + window(x,y0,1,h); + wr_cmd(0x2C); // send pixel + //#if defined TARGET_KL25Z // 8 Bit SPI + for (int y=0; y<h; y++) { + spi.write(color >> 8); + spi.write(color & 0xff); + } + /* #else + SPI::format(16,3); // switch to 16 bit Mode 3 + for (int y=0; y<h; y++) { + SPI::write(color); + } + SPI::format(8,3);*/ + //#endif + cs = 1; + //WindowMax(); + return; +} + +void fillcircle(int x0, int y0, int r, int color) +{ + int x = -r, y = 0, err = 2-2*r, e2; + do { + vline(x0-x, y0-y, y0+y, color); + vline(x0+x, y0-y, y0+y, color); + e2 = err; + if (e2 <= y) { + err += ++y*2+1; + if (-x == y && e2 <= x) e2 = 0; + } + if (e2 > x) err += ++x*2+1; + } while (x <= 0); +} + + +void circle(int x0, int y0, int r, int color) +{ + + int x = -r, y = 0, err = 2-2*r, e2; + do { + pixel(x0-x, y0+y,color); + pixel(x0+x, y0+y,color); + pixel(x0+x, y0-y,color); + pixel(x0-x, y0-y,color); + e2 = err; + if (e2 <= y) { + err += ++y*2+1; + if (-x == y && e2 <= x) e2 = 0; + } + if (e2 > x) err += ++x*2+1; + } while (x <= 0); + } + void fillrect(int x0, int y0, int x1, int y1, int color) +{ + + int h = y1 - y0 + 1; + int w = x1 - x0 + 1; + int pixel = h * w; + //window(x0,y0,w,h); + wr_cmd(0x2C); // send pixel + //#if defined TARGET_KL25Z // 8 Bit SPI + for (int p=0; p<pixel; p++) { + spi.write(color >> 8); + spi.write(color & 0xff); + } + /*#else + SPI::format(16,3); // switch to 16 bit Mode 3 + for (int p=0; p<pixel; p++) { + SPI::write(color); + } + SPI::format(8,3); + #endif*/ + cs = 1; + //WindowMax(); + return; +} + +void I2cstart(void) +{ +SDA=1;SCL=1; /* SCL,SDAは常時Highとする */ + wait_us(2); + SDA=0; + wait_us(2); // SDA出力 +} + + void I2cstop(void) +{ + SCL=0; // 先にSDA Low + wait_us(2); + SDA=0; // SCL Low + wait_us(2); + SCL=1; // SDA Low // 出力モードに戻す SDA =Low + wait_us(2); + SDA=1; // 先にSCLをHigh + wait_us(2); + // 後からSDAをHigh + +} + void I2cout(unsigned char datar) +{ + int ia; + for(ia=0;ia<8;ia++){ + SCL=0; + if(datar & 0x80){SDA=1;} + else SDA=0; + datar<<=1; + wait_us(1); + SCL=1; + wait_us(2); + SCL=0; + wait_us(1);//wait(); + } + wait_us(1); + + SCL=1; + datar<<=1; + wait_us(2); + SCL=0; + + wait_us(1); +} + + + void c(unsigned char adrs,unsigned char datak) +{ + I2cstart(); + I2cout(0x42); + I2cout(adrs); + I2cout(datak); + I2cstop(); + wait_ms(10); +} + + +void cam_init(){ + c(REG_COM7, COM7_RESET); //0x12:COM7(Reset,QCIF,Cbar,RGBformat) + wait_ms(200); //200ms + + c(REG_COM7,COM7_RGB|COM7_FMT_QCIF); //0x12:COM7 , 0x0C) //QCIF, RGB + + c(REG_RGB444, 0x00); //0x8c:RGB 444 control + c(REG_COM1, 0x00); //0x40 //0x04:COM1(CCIR656,AEC) //0) //0x40) + c(REG_COM15, COM15_R01FE|COM15_RGB565); //0x40:COM15 + + c(REG_COM9, 0x48); // 38 0x14:COM9=max AGC gain ceiling, Freeze AGC/AEC + + //c(0x3d,0xc3); //(REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2) //0x3d:COM13 + c(REG_HAECC7,0x94); //0xaa:Hist AEC/AGC control 7 c(0xAA,0x94) //AEC algorithm + + c(REG_TSLB,0x04); //0x3a:Neg,UVval,YUYV,window TSLB_YLAST) //0x04) //0x0C) //0x80) //0x00) //0x04) + c(0x20,0x04); //ADCCTR0, A/D range&ref, mu0102 + + /******* ringo *********/ + c(REG_COM8,0xfd); //AGC,AWB OFF,res OK + + c(0x10,0x0f);//AECコントロール(中位ビット) + c(0x07,0x00);//AECコントロール(上位ビット) + //by Mr.Shiono + + c(0x01,0x40); + c(0x02,0x60); + c(0x03,0x0a); + c(0x0c,0x00); + c(0x0e,0x61); + c(0x0f,0x4b); + c(0x15,0x00); + c(0x16,0x02); + c(0x17,0x18); //HSTART + c(0x18,0x01); + c(0x19,0x02); + c(0x1a,0x7a); + c(0x1e,0x07); + c(0x21,0x02); + c(0x22,0x91); + c(0x29,0x07); + c(0x32,0xb6); + c(0x33,0x0b); + c(0x34,0x11); + c(0x35,0x0b); + c(0x37,0x1d); + c(0x38,0x71); + c(0x39,0x2a); + c(0x3b,0x92);//com11 ナイトモード + c(0x3c,0x78); + c(0x3d,0xc3); + c(0x3e,0x00); + c(0x3f,0x00); + c(0x41,0x08); + c(0x41,0x38); + c(0x43,0x0a); + c(0x44,0xf0); + c(0x45,0x34); + c(0x46,0x58); + c(0x47,0x28); + c(0x48,0x3a); + c(0x4b,0x09); + c(0x4c,0x00); + c(0x4d,0x40); + c(0x4e,0x20); + c(0x4f,0x80);//c(0x4f,0x80); 彩度調整 + c(0x50,0x80);//c(0x50,0x80); + c(0x51,0x00); + c(0x52,0x22);//c(0x52,0x22); + c(0x53,0x5e);//c(0x52,0x5e); + c(0x54,0x80);//c(0x54,0x80); + c(0x56,0x40); + c(0x58,0x9e); + c(0x59,0x88); + c(0x5a,0x88); + c(0x5b,0x44); + c(0x5c,0x67); + c(0x5d,0x49); + c(0x5e,0x0e); + c(0x69,0x00); + c(0x6a,0x40); + c(0x6b,0x0a); + c(0x6c,0x0a); + c(0x6d,0x55); + c(0x6e,0x11); + c(0x6f,0x9f); + c(0x70,0x3a); + c(0x71,0x35); + c(0x72,0x11); + c(0x73,0xf0); + c(0x74,0x10); + c(0x75,0x05); + c(0x76,0xe1); + c(0x77,0x01); + c(0x78,0x04); + c(0x79,0x01); + c(0x8d,0x4f); + c(0x8e,0x00); + c(0x8f,0x00); + c(0x90,0x00); + c(0x91,0x00); + c(0x96,0x00); + c(0x96,0x00); //? + c(0x97,0x30); + c(0x98,0x20); + c(0x99,0x30); + c(0x9a,0x00); + c(0x9a,0x84); //? + c(0x9b,0x29); + c(0x9c,0x03); + c(0x9d,0x4c); + c(0x9e,0x3f); + c(0xa2,0x02); + c(0xa4,0x88); + c(0xb0,0x84); + c(0xb1,0x0c); + c(0xb2,0x0e); + c(0xb3,0x82); + c(0xb8,0x0a); + c(0xc8,0xf0); + c(0xc9,0x60); + c(0x6b,0x40);//入力クロックx4 + c(REG_CLKRC,0x40); //0xaf //PCLK*(1/48) + +} + + + +void camdma_start() +{ +if(flag_dma==0){ + HAL_DMA_Start_IT(&DMA_HandleType/*DMA初期設定構造体*/, (uint32_t)&GPIOB->IDR/*&0x00ff転送元アドレス*/, (uint32_t)dma_buf/*転送先アドレス*/,43500/*データ転送回数*/); + + HAL_SPI_Transmit_DMA(&spi1, (uint8_t*)dma_buf, sizeof(dma_buf)); + + // HAL_ADC_Start_DMA(&ADC_1_dma,(uint32_t*)ad_dma_buf,3); +} +flag_dma=1; +} \ No newline at end of file