10 Replies Latest reply on Jul 26, 2013 1:10 AM by gayathri.vasudevan

    MANY_TO_ONE with FX3 ARM as consumer?

    user_193124556
              Good afternoon, I have an FX3 design with a 32-bit, 100MHz GPIF interface. In this particular application the GPIF interface is receiving data from an external FPGA (one direction, FPGA -> FX3 only). Before I work on the USB3 side of the design I would like to verify the GPIF interface data transfer. To do this I am trying to set up a multichannel DMA transfer to the CPU. The final product will be a multichannel DMA transfer from the GPIF interface to a USB IN endpoint. I see that there is CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE, but there is no multichannel MANUAL_IN variant which is the single-channel way of doing this. If I try to configure the consumer of the DMA data to the CPU (CY_U3P_CPU_SOCKET_CONS) CyU3PMultiDmaChannelCreate() returns error 64. To get around this I have set up the consumer socket ID to the first USB consumer socket (CY_U3P_UIB_SOCKET_CONS_0) and in the DMA handler callback, I just discard the DMA data instead of committing it. My DMA setup is otherwise textbook: size = 16384; CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg)); dmaCfg.size = size; dmaCfg.count = 4; dmaCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0; dmaCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1; dmaCfg.consSckId[0] = CY_U3P_UIB_SOCKET_CONS_0; dmaCfg.validSckCount = 2; dmaCfg.dmaMode = CY_U3P_DMA_MODE_BUFFER; dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_ERROR; dmaCfg.cb = gpif_dma_cb; apiRetStatus = CyU3PDmaMultiChannelCreate(&h_gpif_to_cpu, CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE, &dmaCfg); I then go and start an unlimited DMA transfer with the following calls (error checking removed for clarity): apiRetStatus = CyU3PDmaMultiChannelReset(&h_gpif_to_cpu); apiRetStatus = CyU3PDmaMultiChannelSetXfer(&h_gpif_to_cpu, 0, 0); This appears to work fine. I get 8 DMA producer callbacks, and I immediately discard the data in the callback handler: void gpif_dma_cb(CyU3PDmaMultiChannel *chHandle, CyU3PDmaCbType_t type, CyU3PDmaCBInput_t *input) { CyU3PReturnStatus_t apiRetStatus; switch(type) { case CY_U3P_DMA_CB_PROD_EVENT: apiRetStatus = CyU3PDmaMultiChannelDiscardBuffer(chHandle); break; /* ... remaining function code snipped for clarity ... */ } What happens after this is that I do not get any further callbacks. It's like the DMA buffers are stuck in "used" state even though I'm discarding them. If I reset the DMA channel and restart it, it works for another 8 transfers before getting stuck again. What is the correct way to perform multi channel DMA from the GPIF to the FX3 ARM? I'm sure I'm close.   
        • 1. Re: MANY_TO_ONE with FX3 ARM as consumer?
          user_193124556
                  ok that was crap, how does one write a properly-formatted message here?   
          • 2. Re: MANY_TO_ONE with FX3 ARM as consumer?
            user_193124556

            testing p tag

               
                testing div tag   
               

            testing

               
            one two three
            pre tag   
            • 3. Re: MANY_TO_ONE with FX3 ARM as consumer?
              user_193124556

              It appears that the forums support plain old HTML. Trying again:

                 

              Good afternoon,

                 

              I have an FX3 design with a 32-bit, 100MHz GPIF interface. In this particular application the GPIF interface is receiving data from an external FPGA (one direction, FPGA -> FX3 only). Before I work on the USB3 side of the design I would like to verify the GPIF interface data transfer. To do this I am trying to set up a multichannel DMA transfer to the CPU. The final product will be a multichannel DMA transfer from the GPIF interface to a USB IN endpoint.

                 

              I see that there is CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE, but there is no multichannel MANUAL_IN variant which is the single-channel way of doing this. If I try to configure the consumer of the DMA data to the CPU (CY_U3P_CPU_SOCKET_CONS) CyU3PMultiDmaChannelCreate() returns error 64. To get around this I have set up the consumer socket ID to the first USB consumer socket (CY_U3P_UIB_SOCKET_CONS_0) and in the DMA handler callback, I just discard the DMA data instead of committing it.

                 

              My DMA setup is otherwise textbook:

                 

               

                 
               size = 16384;  CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));  dmaCfg.size = size;  dmaCfg.count = 4;  dmaCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0;  dmaCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1;  dmaCfg.consSckId[0] = CY_U3P_UIB_SOCKET_CONS_0;  dmaCfg.validSckCount = 2;  dmaCfg.dmaMode = CY_U3P_DMA_MODE_BUFFER;  dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_ERROR;  dmaCfg.cb = gpif_dma_cb;   apiRetStatus = CyU3PDmaMultiChannelCreate(&h_gpif_to_cpu, CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE, &dmaCfg);
                 

               

                 

              I then go and start an unlimited DMA transfer with the following calls (error checking removed for clarity):

                 

               

                 
               apiRetStatus = CyU3PDmaMultiChannelReset(&h_gpif_to_cpu);  apiRetStatus = CyU3PDmaMultiChannelSetXfer(&h_gpif_to_cpu, 0, 0);
                 

               

                 

              This appears to work fine. I get 8 DMA producer callbacks, and I immediately discard the data in the callback handler:

                 

               

                 
              void gpif_dma_cb(CyU3PDmaMultiChannel *chHandle, CyU3PDmaCbType_t type, CyU3PDmaCBInput_t *input) {  CyU3PReturnStatus_t apiRetStatus;   switch(type) {  case CY_U3P_DMA_CB_PROD_EVENT:   apiRetStatus = CyU3PDmaMultiChannelDiscardBuffer(chHandle);   break;   /* ... remaining function code snipped for clarity ... */ }
                 

               

                 

              What happens after this is that I do not get any further callbacks. It's like the DMA buffers are stuck in "used" state even though I'm discarding them. If I reset the DMA channel and restart it, it works for another 8 transfers before getting stuck again.

                 

              What is the correct way to perform multi channel DMA from the GPIF to the FX3 ARM? I'm sure I'm close.

              • 4. Re: MANY_TO_ONE with FX3 ARM as consumer?
                gayathri.vasudevan

                 Hi, 

                   

                 

                   

                After the transfer of 8 packets (8 * 16k), is the data actually being driven from FPGA? I believe you are using Slave FIFO state machine in FX3. If so, is the right flag monitored from FPGA and is the data actually being driven? Is the appropriate flag changing status appropriately. 

                   

                 

                   

                Regards,

                   

                Gayathri

                • 5. Re: MANY_TO_ONE with FX3 ARM as consumer?
                  user_193124556
                          Yes, the FPGA is sending data whenever the flags indicate that the FX3 can accept data. The issue does not appear to be on the FPGA side. I can see the flags on the FX3 indicate that the FIFO cannot accept data. Once I reset/restart the DMA subsystem the flags show that the FIFOs can once again accept data.   
                  • 6. Re: MANY_TO_ONE with FX3 ARM as consumer?
                    gayathri.vasudevan

                     Hi,

                       

                     

                       

                    You mean to say, initially the flags indicate as buffer not full. As soon as you transfer 8 * 16k packets, flag changes state to indicate that it is full. Even after discarding the data, the flag retains this state. Is this correct? Which flag are you using for this purpose? Can you post the code showing the channel creation, callback, socket - thread mapping ?

                       

                     

                       

                    Regards,

                       

                    Gayathri

                    • 7. Re: MANY_TO_ONE with FX3 ARM as consumer?
                      user_193124556

                      Yes, that is correct:

                         
                          - initialize DMA and GPIF, flags indicate DMA buffers are available     - transfer 8 buffers (4 from each thread) from FPGA into FX3, flags indicate no buffers available     - callback is issuing CyU3DmaMultiChannelDiscardBuffer() each time     - flags do not reset to "buffer available" until CyU3PDmaMultiChannelReset() and CyU3PDmaMultChannelSetXfer() are called
                         

                      the code is described below. Error checking has been removed for clarity. I am using UIB_SOCKET_CONS_0 as a "dummy" destination since there is no MANUAL_IN many-to-one transfer option, and in fact I get a setup error if I try to use the processor consumer ID.

                         
                       /* DMA setup */  size = 16384;  CyU3PMemSet((uint8_t *)&dmaCfg, 0, sizeof(dmaCfg));  dmaCfg.size = size;  dmaCfg.count = 4;  dmaCfg.prodSckId[0] = CY_U3P_PIB_SOCKET_0;  dmaCfg.prodSckId[1] = CY_U3P_PIB_SOCKET_1;  dmaCfg.consSckId[0] = CY_U3P_UIB_SOCKET_CONS_0;  dmaCfg.validSckCount = 2;  dmaCfg.dmaMode = CY_U3P_DMA_MODE_BUFFER;  dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_ERROR;  dmaCfg.cb = gpif_dma_cb;   apiRetStatus = CyU3PDmaMultiChannelCreate(&h_gpif_to_cpu, CY_U3P_DMA_TYPE_MANUAL_MANY_TO_ONE, &dmaCfg);   /* set up continuous DMA transfer */  apiRetStatus = CyU3PDmaMultiChannelReset(&h_gpif_to_cpu);  apiRetStatus = CyU3PDmaMultiChannelSetXfer(&h_gpif_to_cpu, 0, 0);    /* DMA callback */ void gpif_dma_cb(CyU3PDmaMultiChannel *chHandle, CyU3PDmaCbType_t type, CyU3PDmaCBInput_t *input) {  CyU3PReturnStatus_t apiRetStatus;   switch(type) {  case CY_U3P_DMA_CB_PROD_EVENT:   apiRetStatus = CyU3PDmaMultiChannelDiscardBuffer(chHandle);   break;   /* ... remaining function code snipped for clarity ... */  }; }
                         

                      My understanding is that CyU3PDmaMultiChannelDiscardBuffer() should free up the DMA buffer, but it does not appear to do so.

                      • 8. Re: MANY_TO_ONE with FX3 ARM as consumer?
                        gayathri.vasudevan

                         Hi,

                           

                         

                           

                        Please clarify which are the flags that you are monitoring from FPGA? What flags to correspond to which threads (like TH0_RDY etc). Also, let me know what status of the flag (high/ low) are you checking from FPGA for writing to FX3?

                           

                         

                           

                        Regards,

                           

                        Gayathri

                        • 9. Re: MANY_TO_ONE with FX3 ARM as consumer?
                          david.austin

                          I'm trying to achieve a similar outcome.

                             

                          Cypress really needs to document how to do this.

                          • 10. Re: MANY_TO_ONE with FX3 ARM as consumer?
                            mvillasana_1497601

                            Hello,

                               

                            did your issue ever get resolved?