cancel
Showing results for 
Search instead for 
Did you mean: 

Interfacing OV7670 camera with STM32F4 (no FIFO)

MCarp
Associate

I have to interface my STM32F401RE with an OV7670 camera module without external AL422. My aim is to be able to capture an image on request, so I tried to adapt the code structure used for one of the many Arduino tutorial to my board and HAL library but the results are quite frustrating because all I could get are messy noisy images, like these

0690X000009Z1XRQA0.png0690X000009Z1XMQA0.png

At the moment what my code does is taking an image and send it via UART where a Java application is listening the COM port and shows the image. Some more details:

  • I'm sure about the Java code correctness because if I send an image made of a single color it is perfectly shown;
  • I set the camera using QQVGA resolution and YUV color mode, the register values are the same that can be found surfing a bit on the net;
  • I tried both sending the image in stream, as in the first picture, and saving it in SRAM and then sending, second picture (there is a quite notable difference because the second case seems largely pure noise);
  • At the moment the camera is fed with a 8MHz clock form MCO pin that according many users seems to work even if the datasheets states 10MHz as minimum;
  • I played a bit with camera internal clock prescaling, but always striped messy images;
  • Sender and receiver baud rates are correct.

I am almost sure that there is some problem in reading signals correctly according the camera timing but I really cannot spot the problem, also because I haven't an oscilloscope to help me. In my current settings PCLK does not toggle during horizontal blanking. The main function to capture the image is the following (almost the same that can be found surfing the net):

int camera_capture_image(uint8_t image_buffer[][2*COLS]) {
	uint16_t hg = 120, wg = 320, lg2;
	int num = 0;
	uint8_t buf[320];
	while(HAL_GPIO_ReadPin(VSYNC_PORT, VSYNC_PIN) == GPIO_PIN_RESET);
	while(HAL_GPIO_ReadPin(VSYNC_PORT, VSYNC_PIN) == GPIO_PIN_SET);
	while(hg--){
			uint8_t*b=buf,*b2=buf;
			lg2=wg/5;
			while(lg2--){
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_SET);
				*b++=(uint8_t)GPIOC->IDR;
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_RESET);//wait for high
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_SET);//wait for low
				*b++=(uint8_t)GPIOC->IDR;
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_RESET);//wait for high
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_SET);//wait for low
				*b++=(uint8_t)GPIOC->IDR;
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_RESET);//wait for high
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_SET);//wait for low
				*b++=(uint8_t)GPIOC->IDR;
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_RESET);//wait for high
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_SET);//wait for low
				*b++=(uint8_t)GPIOC->IDR;
				image_buffer[hg][lg2] = *b2++;
				num++;
				//HAL_UART_Transmit(&huart2, b2++, sizeof(b2), HAL_MAX_DELAY);
				while(HAL_GPIO_ReadPin(PCLK_PORT, PCLK_PIN) == GPIO_PIN_RESET);//wait for high
			}
			/* Finish sending the remainder during blanking */
			lg2=320-(wg/5);
			while(lg2--) {
				image_buffer[hg][lg2] = *b2++;
				num++;
				//HAL_UART_Transmit(&huart2, b2++, sizeof(b2), HAL_MAX_DELAY);
			}
		}
		return num;
}

If you need any other detail I am ready to provide it.

1 REPLY 1

So you're basically bit-banging the interface.

Probably not going to get many bites on this, you're a bit off in left field here.

Would probably hard code the pin reading, the HAL code probably runs a dozen cycles.

Review with a scope/analyzer, tracking your progress in the loops with another GPIO toggling.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..