Showing results for 
Search instead for 
Did you mean: 
Honored Contributor I

Connecting OV9655 Camera to Cyclone II Board (Qsys/Nios)


I'm a beginner at the FPGA domain, and would be grateful for any help. 



I have a Cyclone II EP2C35 board with SDRAM and DM9000A Ethernet controller. I want to connect a small OV9655 camera module, and to transmit a single frame over Ethernet - just as a self learning project. (I'm using Quartus 11) 


The camera has the same interface as other omnivision modules, which means 8-bit data (can use 10-bit mode but not in my setup), HSync, VSync and Pclk (pixel clock).  

It also has Xclk pin which is the input clock - I'm using 25[MHz] clock from a PLL. An I2C interface is used for configuring the camera, I've connected a different microcontroller to the I2C interface in order to conveniently configure it to QQVGA mode as defined here: 



As for the FPGA/Nios system so far I have done this: 

- Built a qsys system which includes SDRAM controller, SGDMA (Stream-to-Memory), DC FIFO, and added interfaces for DM9000A and OV9655. The main clock input is 50[MHz].  


- With the Nios II EDS IDE I've tested the DM9000A driver which is working fine - I'm succecfuly sending UDP packets over the net. Also writing and reading from the SDRAM works fine.  

- I'm Using the code for SGDMA from  


Now I'm trying to run the DMA transfer of 160x120 QQVGA frame (which at RGB565 mode is 120x160x2 bytes long, and over the 32-bit wide SDRAM memory is actually 160x120x2/4 = 9600 words ) 

The problem is that the data I'm getting inside the SDRAM after running the DMA descriptor seems malformed.. 

For example, I've attached the Signaltap output of the first bytes of a frame:  


As can be seen, it is supposed to be an alternating sequence of 0x80, 0xc3, 0x80, 0xc3 etc. (The camera is configured to Colorbar test mode) 

But when I'm checking the SDRAM memory at the debugger, I can see it read a sequence like: 0x80, 0xc3, 0x80, 0x80, 0x80, 0xc3 etc. 


The problem is probably somewhere along the OV9655->DCFIFO->SGDMA->SDRAM chain. 

I've put the DCFIFO because I thought that the use of 25[MHz] pixel clock along with the 50[MHz] SGDMA driven clock may cause problem to the stream, but not sure if this is correct. 


Attached the code for running for the SGDMA transfer: 

/* Open a SG-DMA for ST-->MM */ alt_sgdma_dev * transmit_DMA = alt_avalon_sgdma_open(SGDMA_ST_TO_MM_NAME); alt_sgdma_descriptor *transmit_descriptors, *transmit_descriptors_copy; alt_u32 return_code; /************************************************************** * Making sure the SG-DMAs were opened correctly * ************************************************************/ if(transmit_DMA == NULL) { printf("Could not open the transmit SG-DMA\n"); return 1; } /************************************************************** * Allocating descriptor table space from main memory. * * Pointers are passed by reference since they will be * * modified by this function. * ************************************************************/ return_code = descriptor_allocation(&transmit_descriptors, &transmit_descriptors_copy, NUMBER_OF_BUFFERS); if(return_code == 1) { printf("Allocating the descriptor memory failed... exiting\n"); return 1; } for (n=0; n< NUMBER_OF_BUFFERS; n++) { alt_avalon_sgdma_construct_stream_to_mem_desc(&transmit_descriptors, // descriptor &transmit_descriptors, // next descriptor (alt_u32 *)SDRAM_BASE + BUFFER_LENGTH*n, // write buffer location (alt_u16)BUFFER_LENGTH, // length of the buffer 0); // writes are not to a fixed location } alt_dcache_flush_all(); /************************************************************** * Register the ISRs that will get called when each (full) * * transfer completes * ************************************************************/ alt_avalon_sgdma_register_callback(transmit_DMA, &transmit_callback_function, (ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK), NULL); /************************************************************** * Starting both the transmit and receive transfers * ************************************************************/ printf("Starting up the SGDMA engines\n"); /* Prime the SGDMA engines with the descriptor lists (first one, it's a linked list) */ if(alt_avalon_sgdma_do_async_transfer(transmit_DMA, &transmit_descriptors) != 0) //if(alt_avalon_sgdma_do_sync_transfer(transmit_DMA, &transmit_descriptors) != 0) { printf("Writing the head of the transmit descriptor list to the DMA failed\n"); return 1; } while(rx_done == 0) {} printf("The transmit SGDMA has completed\n");  


Any help will be much appreciated. 



0 Kudos
1 Reply
Honored Contributor I

The problem probably is that the camera, as Avalon-ST-Source, is 8-bit wide. The SDRAM memory is 32-bit wide. SGDMA should pack each 4-bytes incoming from the streaming source, and write them at once as 32-bit word. 

There is also the issue of two clock domains - 50[MHz] for the main clock and about ~1[MHz] clock (was mistaken at the previous post) for the pixel clock (PCLK). 


I've tried putting DCFIFO for handling the former and Data Format Adapter for the latter, in two configurations: 


a. avalon-st-source (8-bit) -> data format adapter (8-bit to 32-bit) -> avalon-st dcfifo (32-bit, in_clk - pclk, out_clk - 50[mhz]) <-> sgdma (32-bit) -> sdram (32-bit) 


b. avalon-st-source (8-bit) -> avalon-st dcfifo (8-bit, in_clk - pclk, out_clk - 50[mhz]) -> data format adapter (8-bit to 32-bit) <-> sgdma (32-bit) -> sdram (32-bit) 


Both of them didn't work. What eludes me is what happens at the DCFIFO<->SGDMA.  


I have a few questions -  


1. If the SGDMA is driven by the main clk, and its "in" stream is connected to the "out" port of the DCFIFO, does it means that when in Nios I begin dma transfer it will start clocking the fifo at 50[Mhz] and will not transmit data whenever the fifo is empty - which will happen most of the time because the PCLK is much slower ? 

2. If The Data Format Adapter is driven by PCLK, and it packs every four 8-bit symbols to 1 word, does it means that is will output data only at quarter rate of PCLK ? Or is it outputting some garbage in between? In that case what should be my in_clk for the DCFIFO? (configuration a


What is the best configuration to achieve this [8-bit/clk_A] to [32-bit/clk_B] streaming task?