PSoC5LP to ONFI NAND Flash (DMA, FAST!)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Problem:

   

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.

   

Proposed Solution:

   

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.

   

Issue:

   

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!

0 Likes
8 Replies
himam_31
Employee
Employee
50 likes received 25 likes received 10 likes received

Hello,

   

 

   

Can you please comment how many bytes you want to transfer all together? Is it okay to give the transfer count as the total number of bytes, bytes per burst as 1 byte and each burst needs request. Do you need an hardware interrupt after each byte? In this case the hardware request will be generated after complete transfer. Also the DMA transfer will stop after the whole transfer.

   

Please let us know if this mode will be helpful for your application.

   

 

   

Thanks,

   

Hima

0 Likes
Anonymous
Not applicable

I want to move 2048 bytes into a given page of ONFI Flash. I intend on filling the entire flash by the time that I am done which should be several Giga-bit. The memory interface is asynchronous, I was hoping to use the fact that if I had 1 byte dma transfers that I would get a end of transer signal for each byte from the dma controller that way I could know it was safe to toggle the write enable to flash.

0 Likes
Anonymous
Not applicable

So, I just did some experiments, and I was able to make sense of them after reading the data sheet. It looks like that if you set the transfer and burst length to 1 and set the next TD so that you reload the same TD again,  the SRC/DSC increment don't really matter. The address increment feature is for within a burst.

   

Increment SRC_ADR according to the size of each data transaction in the burst. This should be used when the next transfer should be from a different address than the previous transfer.

   

The result that this gave me for my SRAM to SRAM test with the DMA was that the same first byte was transferred from one array to the next. This is disappointing since the data request and data delivered part of the scheme seemed very promising.

0 Likes
himam_31
Employee
Employee
50 likes received 25 likes received 10 likes received

Hello,

   

If you need toggle after each byte then you can go for Indexed DMA configuration. Here you need to use another DMA which will write the destination register of the first DMA.

   

Please refer to the Application Note "AN84810 - PSoC® 3 and PSoC 5LP Advanced DMA Topics"(Link:AN84810 - PSoC® 3 and PSoC 5LP Advanced DMA Topics).

   

Thanks,

   

Hima

0 Likes
Anonymous
Not applicable

Thank you HIMA, that solution makes sense, it's a bit more complicated than what I wanted, but it can do in a pinch!

   

I have an issue dealing with my building my custom verilog component right now. When I am building my project, I get an error in the file "my_project.v" that reads "A single 'if' statement testing asynchronous conditions is expected"

   

 

   

The error is pointnig at the following:

   

// Component: OneTerminal
`ifdef CY_BLK_DIR
`undef CY_BLK_DIR
`endif

   

`ifdef WARP //error here
`define CY_BLK_DIR "$CYPRESS_DIR\..\psoc\content\cyprimitives\CyPrimitives.cylib\OneTerminal"
`include "$CYPRESS_DIR\..\psoc\content\cyprimitives\CyPrimitives.cylib\OneTerminal\OneTerminal.v"
`else
`define CY_BLK_DIR "C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\psoc\content\cyprimitives\CyPrimitives.cylib\OneTerminal"
`include "C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\psoc\content\cyprimitives\CyPrimitives.cylib\OneTerminal\OneTerminal.v"
`endif

   

 

   

Any advice on what could be the issue? Project or dependency settings? 

0 Likes
Anonymous
Not applicable

The error that I saw was actually an error in my components verilog code. It had reported the error in the "my_project.v" instead of my components verilog code file, the line of the reported error seemed to be correct though.

0 Likes

Hello 

   

Please let us know if you can attach the complete project. We will have a look at the error.

   

Thanks,

   

Hima

0 Likes
Anonymous
Not applicable

Hi jlangfo5,

   

I'm looking at a similar problem - need to playback audio from NAND flash. Any follow-up advice or hints? How did this approach work out in the end?

   

KellyC

0 Likes