ESP32p4 CSI receiver API error
Posted: Tue May 06, 2025 11:52 am
Hi, I am trying to receive CSI-2 data from my IMX219 camera, but the p4 doesn't seem to reach the frame complete callback. I receive the warning 'csi recv API, transaction queue is full, failed to send transaction data to the que'. I am trying to use the isp to convert RAW8 to RGB888. I think I misconfigured the isp or just misunderstood how it takes the data from the camera.
Code: Select all
i2c_master_dev_handle_t IMX219_i2c_handle = NULL;
const i2c_device_config_t imx219_i2c_dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = IMX219_I2C_ADDRESS,
.scl_speed_hz = I2CFASTMODESPEED,
};
esp_cam_ctlr_csi_config_t csi_config = {
.ctlr_id = 0,
.h_res = CAM_H_RES, // 640
.v_res = CAM_V_RES, //480
.lane_bit_rate_mbps = 255,
.input_data_color_type = CAM_CTLR_COLOR_RAW8,
.output_data_color_type = CAM_CTLR_COLOR_RGB888,
.data_lane_num = 2,
.byte_swap_en = false,
.queue_items = 1,
};
esp_cam_ctlr_handle_t cam_handle = NULL;
esp_isp_processor_cfg_t isp_config = {
.clk_hz = 80 * 1000 * 1000,
.input_data_source = ISP_INPUT_DATA_SOURCE_CSI,
.input_data_color_type = ISP_COLOR_RAW8,
.bayer_order = COLOR_RAW_ELEMENT_ORDER_BGGR,
.output_data_color_type = ISP_COLOR_RGB888,
.has_line_start_packet = false,
.has_line_end_packet = false,
.h_res = CAM_H_RES,
.v_res = CAM_V_RES,
};
isp_proc_handle_t isp_proc = NULL;
esp_err_t camera_innit(i2c_master_bus_handle_t I2Cbus_handle, cam_callback_data_t callback_data)
{
/////////////////////////////////////
// I2C Camera setup
/////////////////////////////////////
esp_err_t ret;
ret = i2c_master_probe(I2Cbus_handle, IMX219_I2C_ADDRESS, 10);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "i2c probe for IMX219 sensor failed [%d]", ret);
return ESP_FAIL;
}
ret = i2c_master_bus_add_device(I2Cbus_handle, &imx219_i2c_dev_cfg, &IMX219_i2c_handle);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to add IMX219 dev to I2C bus [%d]", ret);
return ESP_FAIL;
}
ESP_LOGI(CAMERA_TAG, "IMX219 found and added to I2C bus");
/////////////////////////////////////
// esp CSI driver setup
/////////////////////////////////////
ret = esp_cam_new_csi_ctlr(&csi_config, &cam_handle);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to setup CSI config [%d]", ret);
return ESP_FAIL;
}
esp_cam_ctlr_evt_cbs_t cbs = {
.on_get_new_trans = get_new_trans,
.on_trans_finished = end_new_frame,
};
ret = esp_cam_ctlr_register_event_callbacks(cam_handle, &cbs, (void *)&callback_data);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Callback setup failed [%d]", ret);
return ESP_FAIL;
}
ret = esp_cam_ctlr_enable(cam_handle);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to enable CSI ctlr [%d]", ret);
return ESP_FAIL;
}
ret = esp_isp_new_processor(&isp_config, &isp_proc);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to add new ISP process [%d]", ret);
return ESP_FAIL;
}
ret = esp_isp_enable(isp_proc);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to enable ISP process [%d]", ret);
return ESP_FAIL;
}
ret = esp_cam_ctlr_start(cam_handle);
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to start CSI ctlr [%d]", ret);
return ESP_FAIL;
}
cam_config_t cam_cfg;
ret = IMX219_setconfig(cam_cfg); // start transmitting from the camera
if (ret != ESP_OK)
{
ESP_LOGE(CAMERA_TAG, "Unable to set default config for IMX219 [%d]", ret);
return ESP_FAIL;
}
ESP_LOGI(CAMERA_TAG, "CSI config completed");
ret = xTaskCreate(CSIreceiveTask, "CSI receiver", configMINIMAL_STACK_SIZE + 2048, (void *)&callback_data, 10, &CSIrx_task);
return ESP_OK;
}
static bool get_new_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)
{
cam_callback_data_t *next_callback_config = (cam_callback_data_t *)user_data;
next_trans->buffer = next_callback_config->buffer;
next_trans->buflen = CAM_BYTESPERFRAME;
return false;
}
static bool end_new_frame(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *next_trans, void *user_data)
{
return false;
}
void CSIreceiveTask(void *arg)
{
ESP_LOGI(CAMERA_TAG, "Started CSI receiver task");
cam_callback_data_t *callback_data = (cam_callback_data_t *)arg;
esp_cam_ctlr_trans_t trans = {
.buffer = callback_data->buffer,
.buflen = CAM_BYTESPERFRAME,
};
esp_err_t ret = ESP_OK;
while (1)
{
ret = esp_cam_ctlr_receive(cam_handle, &trans, 100);
if (ret == ESP_OK)
printf("new frame\n");
else
printf("error [%d]\n", ret);
}
}