2024-12-31 10:02 AM - last edited on 2025-01-02 03:57 AM by SofLit
Im new to the STM32Cube IDE and trying to make a project with CDMI, the minimal idea is to take a picture on button click and send it to a PC via UART.
This is not working, the I2C comunication is working and im getting both HAL_DCMI_LineEventCallback() and HAL_DCMI_VsyncEventCallback() triggering. The HAL_DCMI_FrameEventCallback() is never called
and im always getting Buffer Error since (i belive) the image size is 320*240*3 and my buffer can only reach 65535.
How can i aproach this problem?
Output
UNSAM Space Snap
Author:
Marco A. Mecha
PID: 76, VER: 73
Camera init........ OK
Camera config...... OK
Starting Capture....
Buffer Error
Capture End
Image size: 65535 bytes
Image Resolution: 481 x 22
DCMI Errors: 0
DCMI Frame Nr: 0
Relevant snipet of main()
while(status != RET_OK){
status = ov7670_init(&hdcmi, &hdma_dcmi, &hi2c2);
HAL_Delay(10);
}
my_printf("Camera init........ OK\r\n");
while(status != RET_OK){
status = ov7670_config(OV7670_MODE_QVGA_RGB565);
HAL_Delay(10);
}
my_printf("Camera config...... OK\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
if (!HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin)) {
my_printf("\r\nStarting Capture....\r\n");
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, SET);
ov7670_stopCap();
bufferPointer = 0;
headerFound = 0;
LineEventNr = 0;
VsyncEventNr = 0;
memset(frameBuffer, 0, sizeof frameBuffer);
ov7670_startCap((uint32_t) frameBuffer);
HAL_Delay(1000);
HAL_DCMI_Stop(&hdcmi); // Stop the DCMI
while (1) {
if (bufferPointer >= BUFFER_SIZE ) {
my_printf("Buffer Error \r\n");
break;
}
if (frameBuffer[bufferPointer] == 0xFF){
if (headerFound == 0 && frameBuffer[bufferPointer + 1] == 0xD8) {
my_printf("Found header of JPEG file \r\n");
headerFound = 1;
}
if (headerFound == 1 && frameBuffer[bufferPointer + 1] == 0xD9) {
my_printf("Found EOF of JPEG file \r\n");
bufferPointer = bufferPointer + 2;
break;
}
}
bufferPointer++;
}
// HAL_UART_Transmit_DMA(&huart2, frameBuffer, bufferPointer);
HAL_Delay(100);
my_printf("\r\nCapture End\r\n");
my_printf("Image size: %u bytes \r\n", bufferPointer);
my_printf("Image Resolution: %d x %d \r\n", LineEventNr/VsyncEventNr, VsyncEventNr);
my_printf("DCMI Errors: %d \r\n", ErrorNr);
my_printf("DCMI Frame Nr: %d \r\n", FrameEventNr);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, RESET);
HAL_Delay(500); // Debounce delay
}
2025-01-02 05:01 AM - edited 2025-01-02 05:03 AM
Hello @Marcomech and welcome to the community;
Could you check the DMA configuration?
The DMA must be configured according to the image size (color depth and resolution), and to the capture mode:
• In snapshot mode, the DMA must ensure the transfer of one frame (image) from the DCMI to the desired memory:
– If the image size in words does not exceed 65535, the stream can be configured in normal mode
– If the image size in words is between 65535 and 131070, the stream can be configured in double buffer mode
– If the image size in words exceeds 131070, the stream cannot be configured in double-buffer mode (Take at DMA configuration for higher resolutions section in AN5020)
Example: In case of a resolution that is 1280x1024, the image size is 655360 words (32 bits). This size must be divided into equal buffers, with a maximum size of 65535 for each of them. To be correctly received, the image must then be divided into 16 frame buffers, with each frame buffer size equal to 40960 (lower than 65535).
For more information, I recommend you to look at AN5020 and precisely section 6.4 DMA configuration.
Thank you.
Kaouthar
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.