Skip to content

Concepts First

  • DVP: a parallel camera interface with many data lines and hsync/vsync signals for fast image transfer.
  • Sensor: the camera's core chip (e.g. GC0308), configured over I2C; the example auto-scans to identify it.
  • Crop: takes only part of the frame (416×240 here) to reduce processing, useful when only a region matters.

Example Overview

This page is based on the cam_crop example in the official Bouffalo SDK (examples/peripherals/cam/cam_crop), which demonstrates DVP camera capture with cropping:

  • Auto-scans and identifies the image sensor over I2C (image_sensor_scan);
  • Crops the picture to 416×240 with bflb_cam_crop_hsync/vsync;
  • Configures the DMA output buffer, starts capture, and loops pulling frames (bflb_cam_get_frame_count / get_frame_info / pop_one_frame) for 50 frames.
  • Sibling examples (examples/peripherals/cam/): cam_normal (normal capture), cam_int (interrupt mode), cam_yuv420 (YUV420 output), cam_lcd (camera to LCD display).

Operation Steps

1
Prepare the Hardware

Connect a DVP-interface camera module (the sensor is configured over I2C). Wire the DVP data/clock/hsync/vsync lines per board_dvp_gpio_init(), the camera I2C to I2C0, and power at 3.3V.

2
Enter the Example Directory

Open a terminal and enter the CAM example directory (prerequisite: set up the environment as in Quick Start (Linux) or Windows):

cd examples/peripherals/cam/cam_crop
3
Build the Project

Run the build command. The Ai-M62 (BL616) and Ai-M61 (BL618) belong to the same series, so both use bl616:

make CHIP=bl616 BOARD=bl616dk
4
Flash the Firmware

Connect the board with a USB cable, hold the BOOT button (IO2 on the Ai-M61-32S-Kit), briefly press EN/RST to enter download mode, then flash (replace the serial port with the one on your computer):

make flash CHIP=bl616 COMX=/dev/ttyUSB0
5
Run and Verify

Open a serial tool (baud rate 2000000). The example scans and prints the sensor model (Sensor name: xxx), then captures 50 frames at a cropped 416×240 resolution, printing frame info per frame, and finally loops forever.

Code Execution Flow

The complete execution flow from startup to running is shown below (loop arrows mean repeated execution):

APIs Used by the Example

image_sensor_scan(i2c0, &sensor_config)

Scans and identifies the camera sensor over I2C, returning its config (resolution, register init sequence).

Parameters:

  • i2c: I2C device handle
  • sensor_config: struct image_sensor_config_s * output

Return: 1 on success; 0 on failure

bflb_cam_crop_hsync / bflb_cam_crop_vsync(cam, start, end)

Sets the horizontal/vertical crop range (must be called before bflb_cam_init).

Parameters:

  • cam: CAM device handle (bflb_device_get_by_name("cam0"))
  • start / end: crop start/end pixels

Return: 0 on success; negative error code on failure

bflb_cam_init / bflb_cam_start(...)

Initializes CAM per config (DVP input, output format/buffer) and starts capture.

Parameters: struct bflb_cam_config_s config

Return: 0 on success; negative error code on failure

bflb_cam_get_frame_count / get_frame_info / pop_one_frame(...)

Checks available frames, gets the frame data pointer/size, and pops the processed frame for continuous capture.

Parameters: CAM device handle, frame info outputs

Return: 0 on success; frame info via output params

Complete Code

The complete source below matches the effect described on this page. It is based on the official example (examples/peripherals/cam/cam_crop); the LED pins are adapted to the Ai-M61/62-32S-Kit onboard RGB LED. Collapsed by default, click to expand:

📜 Click to expand cam_crop/main.c full code
c
#include "bflb_mtimer.h"
#include "bflb_i2c.h"
#include "bflb_cam.h"
#include "image_sensor.h"
#include "board.h"
#include "malloc.h"

#define CROP_WQVGA_X           416
#define CROP_WQVGA_Y           240
#define CAM_OUTPUT_BUFFER_SIZE (CROP_WQVGA_X * CROP_WQVGA_Y * 2 * 2)
#define CAM_FRAME_COUNT_USE    50

static struct bflb_device_s *i2c0;
static struct bflb_device_s *cam0;

int main(void)
{
    uint32_t i, pic_size;
    uint8_t *pic;
    struct bflb_cam_config_s cam_config;
    struct image_sensor_config_s *sensor_config;

    board_init();
    board_dvp_gpio_init();

    i2c0 = bflb_device_get_by_name("i2c0");
    cam0 = bflb_device_get_by_name("cam0");

    if (image_sensor_scan(i2c0, &sensor_config)) {
        printf("\r\nSensor name: %s\r\n", sensor_config->name);
    } else {
        printf("\r\nError! Can't identify sensor!\r\n");
        while (1) {}
    }

    /* Crop resolution_x, should be set before init */
    bflb_cam_crop_hsync(cam0, 112, 112 + CROP_WQVGA_X);
    /* Crop resolution_y, should be set before init */
    bflb_cam_crop_vsync(cam0, 120, 120 + CROP_WQVGA_Y);

    memcpy(&cam_config, sensor_config, IMAGE_SENSOR_INFO_COPY_SIZE);
    cam_config.with_mjpeg = false;
    cam_config.input_source = CAM_INPUT_SOURCE_DVP;
    cam_config.output_format = CAM_OUTPUT_FORMAT_AUTO;
    cam_config.output_bufaddr = (uint32_t)memalign(32, CAM_OUTPUT_BUFFER_SIZE);
    if (cam_config.output_bufaddr == 0) {
        printf("\r\nError! Can't allocate memory!\r\n");
        while (1) {}
    }
    cam_config.output_bufsize = CAM_OUTPUT_BUFFER_SIZE;

    bflb_cam_init(cam0, &cam_config);
#if defined(BL618DG)
    bflb_cam_int_mask(cam0, CAM_INTMASK_NORMAL, false);
#endif
    bflb_cam_start(cam0);

    for (i = 0; i < CAM_FRAME_COUNT_USE; i++) {
        while (bflb_cam_get_frame_count(cam0) == 0) {}
        pic_size = bflb_cam_get_frame_info(cam0, &pic);
#if defined(BL618DG)
        bflb_cam_int_clear(cam0, CAM_INTCLR_NORMAL);
#else
        bflb_cam_pop_one_frame(cam0);
#endif
        printf("pop picture %d: 0x%08x, len: %d\r\n", i, (uint32_t)pic, pic_size);
    }

    bflb_cam_stop(cam0);

    //for (i = 0; i < pic_size; i++) {
    //    printf("%02x", pic[i]);
    //}
    //printf("\r\n");

    printf("end\r\n");

    while (1) {
        bflb_mtimer_delay_ms(1000);
    }
}

FAQ

Can't identify sensor

The camera I2C address or wiring is wrong: confirm the sensor is in the image_sensor component list, and that SDA/SCL are connected with shared ground and power.

Frame count does not increase

Confirm the DVP data/clock/hsync/vsync lines are correct and the sensor is outputting; confirm the output buffer allocated (memalign) and large enough for 416×240×2×2.

I want another resolution

Change CROP_WQVGA_X/Y and the crop ranges, and adjust CAM_OUTPUT_BUFFER_SIZE accordingly.

Have questions?

For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23