I have a setup with a bare metal stm32F407VGT6 board and it is connected to the ov7670 pins via DCMI and I2C and a st7735 display via SPI. When i debugged by code, I could see data being captured and there are some noisy pixels on the display. So I tested by closing the cap on the ov7670 and examined the buffer. The capture buffer shows 0x7fff throughout, even though my selected output format is RGB565.
I have another setup on using a STm32F103 blue pill with ov7670 and st7735 as well and it is using the same settings for the ov7670 and st7735 but it is using arduino code from indrekluuk and it is working perfectly. The difference between the two is that 1) stm32F103 does not have dcmi, so it is using byte transfer from the ov7670 to the st7735 directly.
I have been trying all sorts of ways but it seems that the dcmi will always give me 0x7FFF which is near white when it should be black when dcmi is used.
I am running out of ideas what could be wrong for the dcmi case. I can’t seem to get any valid captures.
SteveStrong has done a lot of work on this to improve the code from indrekluuk so that it uses DMA to read the data from the camera (on the F103C8)
Unfortunatly Steve’s latest code seems to only work on his hardware setup and it only work intermittently for me.
I’m currently using a modified version of some old code posted by Steve as a ZIP file into that thread, and it seems to work OK for me, but I know some other people eg. @kozcap still have problems even with the code that works for me
I’ve also written some code to save the contents of the ILI9341 to a SD card (using a readPixels function written by SteveStrong)
But I think I”m the only person who currently seems to be using that code
I’ve also written some code to read the LCD and send a frame via serial to the PC where I also wrote a Python based viewing program
(I posted all the code for this to the forum as well, so if you dig around you’ll find it) ![]()
Alternatively you could first check if that bit toggles when configured as GPIO output, this would prove that the wiring is ok.
[stevestrong – Fri Oct 06, 2017 9:17 am] –
If you overall get 0x7FFF, it looks like data bit 15 is not correctly wired (or somehow shorten to gnd), check it again.
Alternatively you could first check if that bit toggles when configured as GPIO output, this would prove that the wiring is ok.
The physical port is only 8 bits wide, the DCMI interface will pack two 16-bit RGB565 words into a 32-bit word and DMA to a memory buffer address. The problem is why is it 0x7FFF, RGB565 for black should be zero, why is it giving a white color? Given the init codes for the camera are the same as those in the bluepill setup, the camera “Should” produce the correct info.
For the initialisation itself, i have written the code such that after sending the code to the camera via I2C, I will read the same register to verify that the values match. So I don’t think it is a initialisation code problem. So the only difference is sampling the values from the 8 bit port based on the PIXCLK, HSYNC and VSYNC and then pack them into FIFO and send it to buffer address. But I don’t know what happened in between that the values got changed or somewhat.
How do you check the value? Read from the buffer? Maybe you read an int32 value from a buffer of uint32?
Although zero should be zero anyway…
Or it is because of DCMI settings.
Do you use Embedded data synchronization mode?
Or wrong VSYNC/HSYNC polarity settings?
[stevestrong – Fri Oct 06, 2017 11:19 am] –
Do you have code to share?
How do you check the value? Read from the buffer? Maybe you read an int32 value from a buffer of uint32?
Although zero should be zero anyway…
This is my current work in progress code. Very messy with a lot of various init sets found on the net. The base code has been generated using stm32Cubemx and the ioc file is included. I plan to clean it up and optimize it after I get it working, so… here it is.
The first thing which you should do is to declare the global variables used in ISRs as “volatile”:
volatile uint8_t frameComplete = 0;
volatile uint16_t linecount = 0;
[stevestrong – Fri Oct 06, 2017 11:54 am] –
Have you checked the DCMI interrupts, whether overflow or other error occurred?The first thing which you should do is to declare the global variables used in ISRs as “volatile”:
volatile uint8_t frameComplete = 0;
volatile uint16_t linecount = 0;
Unfortunately AFIK DMA on the F4 is a bit different from the F1, so I suspect Steve’s 103 code would not run on the F4 without modification
https://www.youtube.com/watch?v=vokasVZTJLM&t=948s
https://github.com/take-iwiw/DigitalCamera_STM32
If I find some time I may give a try to make a live camera app for F4, too, using our libmaple core.
[flodejr – Sun Oct 08, 2017 4:16 am] –
But the image colors are still wrong.
I would suggest to contact the owner on github, since nobody here seems to be able to help you out with DCMI.
Its only QVGA 320×240 and only manages 5 fps to SD.
About the only thing it can do that the F103C cant do is JPEG compression, and I suspect we may be able to do JPEG still image compression, if it could be done with an 8 line buffer.
But the F103C8 would not be able to do motion jpeg as that needs multiple complete frame buffers ( though I am not sure whether the F4 has enough RAM for true motion JPEG with frame differencing either.
[stevestrong – Sun Oct 08, 2017 8:53 am] –
My code for F1 does not use DCMI, and my SPI code for F4 is anyway not relevant here, because HAL-based software is used here (see second link).If I find some time I may give a try to make a live camera app for F4, too, using our libmaple core.
[flodejr – Sun Oct 08, 2017 4:16 am] –
But the image colors are still wrong.I would suggest to contact the owner on github, since nobody here seems to be able to help you out with DCMI.
Are you working on the F4 core, just some note about the DMA packing in F4, I am not sure of whether F1 behaves the same way. In the F4, the DMA if set to 16 bits(half word), it will trigger 2 transfers. the orders will be b1,b0 in first transfer, b3,b2 in second transfer. If the DMA is set to word, it will trigger one transfer and the byte order will be b3,b2,b1,b0 and this is giving me a major headache as the cubemx does not allow me to set halfword in non FIFO transfers and there is some note to say that non-FIFO halfword transfers are allowed but not guaranteed accuracy.
BTW, I have several versions of the specs on ov7670 and there are some discrepancy on the CLKRC setting. Some docs say
internal clock = External clock/ (2*(CLKRC+1),
but some docs say
Internal clock = External clock/(CLKRC+1)
I don’t have a scope to verify. Are you able to comment on this?
However I don’t know if the same thing works on the F4 and its not documented as being possible on the F1….
However, this FIFO can be switched off or on.
The DCMI data register should give the bytes in the right order because b1,b0 is stored on the lower addresses, so that if you configure the LCD DMA to send to SPI 16 bits in 16bit mode, it would send the data from the same buffer to SPI in the correct endianess and order: first (b1,b0) and then (b3,b2)
If non-FIFO in 16bit mode is critical for the DMA (I would anyway suggest you to try it out), then you should turn the FIFO on.
Btw, what exactly means non-FIFO halfword transfers are allowed but not guaranteed accuracy. What kind of “accuracy” is not guaranteed?
I could not read in F4 reference manual about any restriction on programing the transferred data width. This can be set to be 8, 16 or 32 bit without any problem. The memory pointer will then be incremented accordingly.
Which means you should be able to transfer the data from memory to SPI data register without any problem in non-FIFO (direct) mode, either in 8 or 16 bit mode as well (which is currently working in the SPI lib).
Re: Direct camera to SPI
That takes some load from the processor, but SPI is much slower then that data rate possible from the camera, so I dont know what benefit it would be, unless the processor needs to do some unrelated activity.
e.g. If the data is going straight from the camera to the LCD, the processor cant do any image processing etc.
So an intermediate memory buffer is inevitable. And it makes sense, one could use double buffering so that DCMI->memory and memory->SPI transfers with DMA could work quasi in parallel.
I would only like to ask @flodejr whether he managed to bring up the DCMI with HAL.
If so, I would need the values of configuration registers of DCMI and DMA(stream1) to compare them with my setup, maybe I can find any error.
