Hey, I have gotten myself a little bit stumped here. I plan on moving data from a SAR ADC (480kbps) to SRAM with DMA (already done), and buffering it before moving it to an external ONFI NAND Flash. I would like to run the bus clock (cpu clock) as slow as possible, let's say 3 Mhz in order to save power. I tried doing this with the CPU and got less than stellar results, so I decided it would be a good idea to us the digital blocks to operate the bus to the ONFI Program Page sequence. The EMIF component does not seem like it would be a good match since does not support ONFI NAND and the custom EMIF seems like all the same work of implementing the bus in verilog.
Implement the ONFI Program Page Sequence using the digital blocks to generate the control signals and DMA to move data in tandem with the WE signal from the SRAM to the GPIO pins. Let the DMA Controller assert the end of transfer signal after it has moved a byte to the GPIO so the digital blocks know that it's ok to assert the WE signal. Then assert a data request signal to the DMA controller letting it know that it's ok to transfer the next byte to the GPIO pins.
I am not sure of a good way to set up the DMA transfer. My page size is to large to just simply chain together enough dma descriptors to were each descriptor waits on a data request and terminates once the entire chain is finished. The other approach that I thought about was using a single dma descriptor to post increment the source address, keep the destination address static, send 1 byte per burst, and require a request per given burst. If set the transfer length to 1 byte long as well, I would get my data request (nrq) signal at the end of the transfer. I would have to set the next TD so that it would loop also. However, in this case, I am not sure how to stop the DMA and set the source address back to the start of my ram buffer so that when I am ready to write the next page, I can start again.
So, what would be really great, would be a circular DMA buffer that sends 1 byte per data request and let me know when that byte was sent, and would loop around to the start of the buffer once it had sent a page worth of bytes.
In case anyone finds it helpful in understanding what I am trying to do, I am attaching a timing diagram for the program page sequence.
Thanks in advance!
program_page_0.png 19.8 K