1 2 Previous Next 19 Replies Latest reply on Feb 26, 2014 1:23 AM by user_318879994

    PSoC 5LP DMA Transfert and Addresses Incrementation


      Hello All,


      I don't find answer in applications notes and examples includes in PSoC Creator, can you tell me/explain me how i can configure DMA to increment address by more than one step address. To precise my issue, i need to start stored data in address 0x00 (for example) next data in address 0x03 and next ... but for this moment i use the "TD_INC_DST_ADR" and it is not good in my application.


      Thank's in advance.

        • 1. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

          The address is inced according to the size of data you indicate


          in transfer -





          • 2. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

            INC_DST_ADR increments according to the transfer size for each block. So if you transfer 4 bytes per transaction, it will increment by 4. Or do you transfer only single bytes, but need to scatter them into memory?


            (I remember to see an AppNote explaining that, but cannot find it right now :(

            • 3. Re: PSoC 5LP DMA Transfert and Addresses Incrementation



              In fact my DMA transfert from Status register one byte by one byte to SRAM.


              I need to describe my system, i have four status registers, each status register input is connected to 8 bits bus, and each time i detect a bit change (on any of four bytes), i need to transfert simultaneously this four bytes values in SRAM but in an organized manner.


              byte 3 => SRAM Address 0x00, byte 2 => Address 0x01, byte 1 => Address 0x02 and byte0 => Address 0x03 and next event byte 3 => SRAM Address 0x04, byte 2 => Address 0x05 and next... so each 4-byte packet corresponds to an event.


              My idea is to have finaly only one buffer which contain my events informations in an organized manner to then simply transfert via USB by 64-byte packets. i don't know if it is the best way to do this. Four Status register + four DMA + SRAM and USB transfert.


              To return to my first post, i was describing only the system with one status register and one DMA :) , you understand now why i need to jump to 0x00 address to 0x04 address for the same status register and DMA, because i have in same time, three others DMA which should tranfert data in address 0x01, 0x02 and 0x03 :) , so you have right hli, i need scatter them into memory :s . and i don't know if i can do this, i think NO unfortunately.


              Thank's in advance!!!

              • 4. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                Note being a DMA expert, why would not TD chaining take care of this ?




                Here is a white paper, and one example where bytes were swapped in an intermediate












                Regards, Dana.

                • 5. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                  Thank you Dana!


                  I have finished my day :) , tomorow i will post here a schema of system i want to do, a picture is worth a long discuss ;)



                  • 6. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                    According to the link Dana sent you you might


                    Use 4 DMAs to transfer 4 single bytes to a 32-bit var


                    Use 1 DMA to transfer that 4-byte value into your final destination-array.


                    I am curious how you manage to get informed of a single bit-change within your 4 byte-wide status-registers.





                    • 7. Re: PSoC 5LP DMA Transfert and Addresses Incrementation





                      For detect a bit change on one of my buses, i use a edge detector (rising & falling), i parallelize my bus to 8 edges detectors, when a edge is detected, i use the pulse generated to manage a DMA for example or an others components. This seems to be ok because i transfert the 8 bits counter values like this to the SRAM and after on my PC (by USBFS) without losing data. (by 64-byte packet). (1xCounter + 8xEdges detectors + 1xStatus registor + DMA + SRAM_Buffer + 1xUSBFS).




                      I look again carefully Dana's White Paper and your explanation Bob Marlowe. Pending, attached file is two simples schemas will show you what i want to do. But Bob Marlowe, to be honnest with you, i don't understand how i can configured my four DMA to transfert in a single 32 bits variable because the four DMA transfert simultaneously the four bytes. Maybe i can set in DMA parameter not only an destination address but also a position in this address. In this manner, each DMA have the same destination address but write in a differentes locations in this address.




                      Best Regards,





                      • 8. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                        Different DMA-transfers cannot occur simultaneously, there lies a short time between them. My suggestion was to trigger 4 one-byte Transfers with the signal indicating a change to dest[0], dest[1], dest[2] and dest[3]. When all transfers terminated you transfer a 33-byte value from dest to your array keeping the final results.




                        While writing this I get the idea of a (more complicated) but much easier to handle solution: Within PSoC5 you can build your own components. When you create a 32-bit wide datapath component it will be able to detect a bit-change and capture the 32-bit result in a FIFO from which you can directly transfer it with one DMA. All done in hardware.


                        What you need? You'll have to learn VeriLog as Hardware Description Language (HDL) and learn how to use the datapath programming. This solution will use 4 (max.8) of the 24 UDBs within the PsoC and will run with a clock of max. 48MHz and -apart from setup- will need no CPU intervention. You may capture up to 1024 32-bit samples with a single DMA transfer.




                        Hope this doesn't get you headaches



                        • 9. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                          Oops, 33 byte is exactly a bit too much  





                          • 10. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                            Thank you Bob Marlowe,




                            I am agree with you for the second solution, in fact, i have previously already explode this aspect, and i created a custom component (symbol + verilog file + DMA capability xml ) which capture the four bytes and concatenated them in one 32bit word. My component is detected in DMA Wizard (Yeaaah!!) but my issue is to implement the output register of 32 bits which must be transfered by DMA in SRAM. I think it is the datapath configuration but i don't understand this aspect... :/




                            For precise my issue, when i choose in DMA wizard my custom component like source and SRAM like destination, i don't know how specify what are the data pointed in the source.









                            • 11. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                              You should not use the output register of the datapath, but the output FIFO which is 4 entries deep. The fitter will assign a name to the used UDB's FIFOs where you can read from. When got stuck (which seems to be right now) file a MyCase and get help by a Cypress engineer (Top if this page: Support&Community -> Technical Support -> Create a MyCase). Please keep us informed of this process, I'd like to see that solution.





                              • 12. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                                Thank you Bob Marlowe for your advices, i will take time to explore more the custom component aspect and i will contact Cypress engineer!




                                when i have the solution i will share with you!




                                Best Regards,





                                • 13. Re: PSoC 5LP DMA Transfert and Addresses Incrementation





                                  I have finally choose to create my own component! And so i think this is the best way... as promised i will explain you how i do that.




                                  Four 8 bits inputs,  Byte0 => timer[7:0] ; Byte1 => timer[15:8]; Byte2 => timer[23:16] and Byte3 => CNT[7:0].


                                  One output, a DRQ signal for DMA request transfer.




                                  This component contain 4 UDB setup to datapath 32. All UDB are chained (Basic Chaining like in this example http://www.cypress.com/?app=forum&id=2492&rID=76859) in "Datapath Config Tools" and so chained in verilog file (see example http://www.cypress.com/?rID=46730&cache=0 to see a verilog chaining). in each UDB, "A0 WR SRC" and "F0 INSEL" setup to "ALU". We use Parallel Input "PI" on each UDB. (and so PI is connected to A0 and A0 is connected to F0.)




                                  With this first component version, when i read F0 content,i read my 32 bits words with no issue. (CY_GET_REG32(MyComponent_DPConf__F0_REG in cyfitter.h).




                                  In a second time, i need to generate a DRQ, this DRQ is managed by two events. First event, a timer overflow, and second event, a bit change on CNT byte.




                                  Timer overflow handling: It is very easy to do this, i use the UDB datapath output named ".ff0", this output indicate when A0 register is equal to FF. And so when my three timer bytes are equal to FF my DRQ is equal to '1'.




                                  CNT bit change: To do this, i check each bits status with an either edge detector (see APPENDIX B in  http://www.cypress.com/?docID=42936, when posedge or negedge is detected on one of my CNT bit, my drq is equal to '1'.




                                  For resume, F0 content is good and my DRQ generation is good...but i have now another issue. I can't transfer my 32bits data properly with a DMA. In fact, when i read my destination array, datas are wrong. To see this issue, i have connected a digital constant to CNT input, and despite this constant, the CNT bytes in my destination array is not equal to my constant and more it is variable (change at each clk edge).


                                  See my DMA init:

                                      #define DATASIZE 64   
                                      #define DMA_DST_BASE (CYDEV_SRAM_BASE)   
                                      uint8 DMA_Chan;   
                                      uint8 DMA_TD[1];   
                                      uint32 destinationArray[1] = {0};   
                                      DMA_Chan = DMA_SPY_DmaInitialize(4, 1, HI16(xxxxxxxxxx__F0_REG), HI16(DMA_DST_BASE));   
                                      DMA_TD[0] = CyDmaTdAllocate();            
                                      CyDmaTdSetConfiguration(DMA_TD[0], DATASIZE, DMA_TD[0], DMA_SPY__TD_TERMOUT_EN);   
                                      CyDmaTdSetAddress(DMA_TD[0], LO16(xxxxxxxxxxx__F0_REG), LO16((uint32)destinationArray));    
                                      CyDmaChSetInitialTd(DMA_Chan, DMA_TD[0]);   
                                      CyDmaChEnable(DMA_Chan, 1);   

                                  So i have a doubt on my source address...but i don't see where is my issue, because my source address is the same when i read direclty the F0 content in my main and print it on my LCD screen.


                                  To read my destination array:

                                      uint32 databuffer;   
                                      uint16 databufferLSB;   
                                      uint16 databufferMSB;   
                                      databufferMSB = (uint16) (databuffer >>16);   
                                      databufferLSB = (uint16) (databuffer & 0x0000FFFF);   



                                  I don't know if my explain is clear...if you have some questions or if you need more explanation don't hesitate!!




                                  Best regards,





                                  • 14. Re: PSoC 5LP DMA Transfert and Addresses Incrementation

                                    Hello all,


                                    Sorry for this UP...




                                    On the same project, i don't understand why i can't read my UDB FIFO_0 correctly with a DMA, in fact, when i read the content of my FIFO_0 as follow:


                                    uint32 dataout;


                                    dataout = CY_GET_REG32(SpyHandling_Byte0__F0_REG);


                                    The data read are goods. I obtain my 32 bits data.


                                    But with the DMA, configured to 4 bytes per burst, and request per burst set to 1.


                                    source address => SpyHandling_Byte0__F0_REG.


                                    destination address => a tab named destinationArray.


                                    uint32 destinationArray[64];


                                    And i read the SRAM content as follow


                                    uint32 databuffer;


                                    databuffer = CY_GET_REG32(destinationArray);




                                    here, i read four times the same value with my DMA.


                                    To read correctly with my DMA, i must increment the source address, but i think it is not good, because, when i do that, i think that i read the first byte of each F0 FIFO of the 4 UDB chained and not in the same FIFO.




                                    do you have an idea on the cause of this issue?




                                    See attach my UDB component test project. (PSoC5LP CY8CKIT-050 Dev kit)

                                    1 2 Previous Next