OV7670 is a CMOS VGA image sensor with small size and low operating voltage. It is controlled by the SCCB bus and can output 8-bit image data of various resolutions with a frame rate of up to 30 frames/second and low cost.
This article mainly implements the use of CSI on RT10XX to obtain OV7670 camera data, and displays it using the eLCDIF display module that comes with RT10XX. The camera and display use RGB565 format. The camera resolution configuration is QVGA 320*240, the LCD is NXP official EVKB matching LCD RK043FN02H, the resolution is 480*272, and the frame rate is 30FPS.
This article is based on NXP official RT1050 SDK:
SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565
Porting the OV7670 driver to implement the CSI method to collect OV7670 image data and display it on the LCD through the eLCDIF module
Here is a brief explanation of relevant knowledge.
As a basic color coding format for images, RGB565 refers to a pixel that occupies 2 bytes of data and is usually used in images and display devices. R red, G green, B blue, the actual display can obtain different other colors according to the configuration of the three primary colors. Each pixel bit can display 65536 (2^16) colors. The specific allocation is as follows:
Fig 1
From the above figure, we can know that the 2-byte data displayed in pure red, green and blue is:
Red: 0xf800, Green: 0X07E0, Blue: 0X001F
2.2 OV7670 camera hardware and waveform situation
The OV7670 module used is as follows:
Fig 2
Pin situation
No |
Signal |
Description |
1 |
PWDN |
Power consumption selection mode, pull down for normal use |
2 |
RET |
Reset port, pull high for normal use |
3 |
D0 |
Data port output bit 0 |
4 |
D1 |
Data port output bit 1 |
5 |
D2 |
Data port output bit 2 |
6 |
D3 |
Data port output bit 3 |
7 |
D4 |
Data port output bit 4 |
8 |
D5 |
Data port output bit 5 |
9 |
D6 |
Data port output bit 6 |
10 |
D7 |
Data port output bit 7 |
11 |
XLK |
Clock signal input signal |
12 |
PLK |
Pixel clock output signal |
13 |
HS |
Horizontal synchronization signal output signal |
14 |
VS |
Frame sync clock output signal |
15 |
SDA |
SCCB Interface data control |
16 |
SCL |
SCCB Interface clock control |
17 |
GND |
GND |
18 |
3.3V |
3.3V power |
RGB565 output data timing:
Fig 3
Fig 4
Fig 5
Therefore, the data of OV7670 is obtained through CSI and then stored in the buffer. The eLCDIF then retrieves the data from the buffer and displays it on the LCD screen to display the real-time collection and reality of the camera data.
The test platform is based on NXP MIMXRT1050-EVKB revA1 version:
LCD为:https://www.nxp.com/part/RK043FN02H-CT#/
As can be seen from Figure 2, the universal module purchased is a 2.54mm direct plug mode, but the CSI interface used on the MIMXRT1050-EVKB board is an FPC interface, so an adapter board is required to switch from FPC to 2.54mm direct plug mode. The wiring diagram is as follows:
Fig 6
The actual overall hardware connection situation is as follows:
Fig 7
Regarding the SDK driver of OV7670, the RT SDK does not provide it directly, but the FRDM-K82 SDK provides relevant drivers that can be transplanted to the RT1050 SDK.
SDK version:SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565
The code replaces the original OV7725 code, replaces the relevant driver with the OV7670 driver, modifies the OV7670 code, matches it to the RT1050 CSI code, and adds IO signal control for OV7670 RST and PWDN. The reason for adding RST and PWDN control is that it was found Some modules, if the RST pin is not closed and delayed to open, will cause the problem of unsuccessful acquisition. However, with the addition of RST and PWDN control, currently OV7670 from different manufacturers can successfully acquire and display stably. For the specific OV7670 code, you can view the attached source code.
The camera initialization code is as follows:
static void APP_InitCamera(void)
{
const camera_config_t cameraConfig = {
.pixelFormat = kVIDEO_PixelFormatRGB565,
.bytesPerPixel = APP_BPP,
.resolution = FSL_VIDEO_RESOLUTION(320, 240),
/* Set the camera buffer stride according to panel, so that if
* camera resoution is smaller than display, it can still be shown
* correct in the screen.
*/
.frameBufferLinePitch_Bytes = DEMO_BUFFER_WIDTH * APP_BPP,
.interface = kCAMERA_InterfaceGatedClock,
.controlFlags = DEMO_CAMERA_CONTROL_FLAGS,
.framePerSec = 30,
};
memset(s_frameBuffer, 0, sizeof(s_frameBuffer));
BOARD_InitCameraResource();
CAMERA_RECEIVER_Init(&cameraReceiver, &cameraConfig, NULL, NULL);
if (kStatus_Success != CAMERA_DEVICE_Init(&cameraDevice, &cameraConfig))
{
PRINTF("Camera device initialization failed\r\n");
while (1)
{
;
}
}
CAMERA_DEVICE_Start(&cameraDevice);
/* Submit the empty frame buffers to buffer queue. */
for (uint32_t i = 0; i < APP_FRAME_BUFFER_COUNT; i++)
{
CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)(s_frameBuffer[i]));
}
}
The resolution here is QVGA 320*240, which does not match the 480*272 of the LCD, but it does not matter. In fact, the size of 320*240 is displayed in the LCD. If you want to display it to 480*272, you can also configure the size through PXP.
For more code details, see the attached code package.
This article aims to provide a demo of RT OV7670 CSI+eLCDIF acquisition and display. let’s go directly to the finished product effect video. You can see that the relative display is relatively clear, and the refresh effect is also good.