catalogue
2.2 configuration register DCI_CTL
2.2.2 clock polarity selection CKS
2.2.3 Horizontal synchronous polarity selection HPS
2.2.4 Vertical synchronous polarity selection VPS
5. Set the pixel size of OV2640
The digital camera interface is a synchronous parallel interface, which can capture video and image information from the digital camera. It supports different
Color space images, such as YUV/RGB, also support JPEG format images of compressed data.
1 IO initialization
DCI generally selects 8bit interface. In addition, OV2640 requires I2C interface setting register.
2 initialize DCI
2.1 enable DCI and DMA1
RCU_AHB2EN |= ((uint32_t)1 << 0); //Enable DCI RCU_AHB1EN |= ((uint32_t)1 << 22); //Enable DMA1
Generally, DMA function is used when DCI is used. DCI corresponds to channel 1 or channel 7 of DMA1. Channel 7 is used here
2.2 configuration register DCI_CTL
2.2.1 snapshot mode SNAP
0: continuous capture mode - continuous capture of camera data
1: Snapshot mode- Only a single frame is captured. After receiving the complete first frame, the camera interface will be automatically disabled
2.2.2 clock polarity selection CKS
0: falling edge capture
1: Rising edge capture
2.2.3 Horizontal synchronous polarity selection HPS
0: low level during blanking
1: Blanking period high level
2.2.4 Vertical synchronous polarity selection VPS
0: low level during blanking
1: Blanking period high level
2.2.5 Data format DCIF
00: each pixel clock captures 8 bits of data
01: capture 10 bits of data per pixel clock
10: Each pixel clock captures 12 bits of data
11: Each pixel clock captures 14 bits of data
2.2.6 Frame frequency FR
In the continuous capture mode, FR defines the frame capture frequency
00: capture all frames
01: capture every other frame
10: Capture every three frames
11: Reserved
2.3 configuring DMA
Two DMA channels can be used for DCI, i.e. channel 1 and channel 7 of DMA1
DMA_CHFCTL(DMA1, CAMERA_DMA_CH) = 0; DMA_CHCTL(DMA1, CAMERA_DMA_CH) = 0; DMA_CHFCTL(DMA1, CAMERA_DMA_CH) &= ~((uint32_t)1 << 2); //Disable Multi Data Mode DMA_CHPADDR(DMA1, CAMERA_DMA_CH) = (uint32_t)&DCI_DATA; DMA_CHM0ADDR(DMA1, CAMERA_DMA_CH) = ramAddr; DMA_CHCNT(DMA1, CAMERA_DMA_CH) = (uint32_t)CAMERA_SIZE_W * CAMERA_SIZE_H * stride / 4; value = DMA_CHCTL(DMA1, CAMERA_DMA_CH); //bit6-7: channel transfer mode //bit11-12: transfer data width of peripheral //bit13-14: transfer data width of memory //bit16-17: channel priority level value &= ~((uint32_t)0x03 << 11 | ((uint32_t)3 << 13) | ((uint32_t)3 << 16) | ((uint32_t)3 << 6)); value |= (((uint32_t)2 << 11) | ((uint32_t)2 << 13) | ((uint32_t)2 << 16) | ((uint32_t)0 << 6)); //bit9: next address generation algorithm of peripheral value &= ~((uint32_t)1 << 9); //Disable Peripheral's Address Auto Increasing. //bit10: next address generation algorithm of memory value |= ((uint32_t)1 << 10); //Enable Memory's Address Auto Increasing. //bit8: DMA circular mode value |= ((uint32_t)1 << 8); //Enable DMA Circular Mode //bit25-27: peripheral enable value &= ~((uint32_t)0x7 << 25); value |= ((uint32_t)0x1 << 25); //Peripheral 1(DCI is 1) is enable. DMA_CHCTL(DMA1, CAMERA_DMA_CH) = value;
ramAddr is the RAM space allocated to DCI in MCU. For example, here is an array
#define CAMERA_SIZE_W 320 #define CAMERA_SIZE_H 240 EXTERN uint16_t gCameraBuf[CAMERA_SIZE_W * CAMERA_SIZE_H];
The camera adopts RGB565 format, and one pixel corresponds to two bytes, so uint16 is used here_ T defines this array variable, corresponding to stripe = 2 (that is, RGB565 is 2 bytes).
2.4 configure clock output
reg = RCU_CFG0; #if (PIN_DCI_XCLK == 8) /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */ reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV); RCU_CFG0 = (reg | RCU_CKOUT0SRC_HXTAL | RCU_CKOUT0_DIV3); #else reg &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV); RCU_CFG0 = (reg | RCU_CKOUT1SRC_HXTAL | RCU_CKOUT1_DIV3); #endif
3. Enable DCI
void dciEnable(void) { DMA_CHCTL(DMA1, CAMERA_DMA_CH) |= ((uint32_t)1 << 0 | ((uint32_t)0x1 << 4)); //DMA_ENABLE DCI_CTL |= ((uint32_t)1 << 14); //DCI enable DCI_CTL |= ((uint32_t)1 << 0); //DCI capture enable }
It mainly enables DMA and DCI.
4. Initialize OV2640
void ov2640Init(void) { uint8_t buf[1]; uint16_t i; bool_t status = 0; /* OV2640 reset */ buf[0] = 0x01; status = i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0xff, buf, 1); if(status == FALSE) { OV2640_INFO(Printf("ov2640 init fail 1\n")); } buf[0] = 0x80; status = i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0x12, buf, 1); if(status == FALSE) { OV2640_INFO(Printf("ov2640 init fail 2\n")); } delayms(10); for(i = 0; i < sizeof(ov2640_svga_init_reg_tbl) / 2; i++) { status = i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, ov2640_svga_init_reg_tbl[i][0], (uint8_t *)&(ov2640_svga_init_reg_tbl[i][1]), 1); if(status == FALSE) { OV2640_INFO(Printf("ov2640 init fail 3:%d\n", i)); break; } } delayms(100); for(i = 0; i < sizeof(ov2640_rgb565_reg_tbl)/2; i++) { status = i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, ov2640_rgb565_reg_tbl[i][0], (uint8_t *)&(ov2640_rgb565_reg_tbl[i][1]), 1); if(status == FALSE) { OV2640_INFO(Printf("ov2640 init fail 4:%d\n", i)); break; } } delayms(100); }
5. Set the pixel size of OV2640
The pixel size of OV2640 must be 4 multiples
void ov2640SetSize(uint16_t w, uint16_t h) { uint16_t outh; uint16_t outw; uint8_t buf[1]; if((w % 4) > 0) return; if((h % 4) > 0) return; outw = w / 4; outh = h / 4; buf[0] = 0x00; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0xff, buf, 1); buf[0] = 0x04; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0xE0, buf, 1); buf[0] = outw & 0xFF; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0x5A, buf, 1); buf[0] = outh & 0xFF; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0x5B, buf, 1); buf[0] = (outw >> 8) & 0x03; buf[0] |= (outh >> 6) & 0x04; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0x5C, buf, 1); buf[0] = 0x00; i2cWrite(I2C_CAMERA, OV2640_ADDRESS, 8, 0xE0, buf, 1); }
6. Initialize the camera
Finally, the content of the camera is displayed on the TFT screen, so the data needs to be displayed on the TLI.
tliLayer_t layer; ov2640Init(); Printf("OV2640 ID:%x\n", ov2640GetID()); ov2640SetSize(CAMERA_SIZE_W, CAMERA_SIZE_H); dciEnable(); delayms(100); layer.alpha = 0xFF; layer.bufAddr = (uint32_t)gCameraBuf;//(uint32_t)0xC0000000; layer.defalutColor = 0x00FFFFFF; layer.format = FORMAT_RGB565; layer.x = 0; layer.y = 0; layer.w = CAMERA_SIZE_W; layer.h = CAMERA_SIZE_H; tliLayerInit(0, layer, 1);