1 2 Previous Next 16 Replies Latest reply on Dec 20, 2011 7:54 AM by user_78878863

    DMA to GPIO

    manish.ranade.2

       Hello,

         

      Can DMA be setup between (FLASH / SRAM)  memory and GPIO?

         

      My requirement is:

         

      1K data is stored in memory (FLASH / SRAM)

         

      Want to flush this data (8-bit wide) on 8-bit wide GPIO on some event. 

         

      I am new to PSOC. Have gone though example aps of DMAs Mem2Mem, Mem2Peripheral, Peripheral2Peripheral.

         

      Not able to relate my requirement of DMA to GPIO to these examples (if architecture allows to do so)

         

       

         

      Manish

        • 1. Re: DMA to GPIO
          udayan.umapathi

           Hi,

             

          Yes it is possible to do this.

             
                
          • Assume the data being sent is 8 bit wide. Place a Control Register which is available under Digital --> Register folder in the Component Catalog. Configure it for 8 bits.
          •     
          • Connect 8 Pins(GPIOS) to the control register and configure the Pins for Strong drive mode.
          •     
          • Configure a DMA with the source address as SRAM where your data is loacted and destination as the Control Register.
          •     
          • The DMA transfer can be triggered using the DRQ terminal available on the DMA component. With the help of DRQ you can control the rate at which data is transferred.
          •    
                 

          Hope this helps.

             

          -Udayan

          • 2. Re: DMA to GPIO
            udayan.umapathi

             See the image available     here.

            • 3. Re: DMA to GPIO
              manish.ranade.2

               Thanks Udayan for you reply.

                 

              I was not able to figure-out what should be the  "destinatin addrress" for DMA!

                 

              I will try the "control register" method which you have mentioned.

                 

              But wondering, I will need an API to transfer data from control register to port.

                 

              something like: Pin_1_Write( ControlReg_Read() )

                 

              This will "cost" me some CPU cycles and I might not get data "flushed-out" on port on every clock as one would expect in DMA.

                 

              The purpose of using DMA here is, downstream device-FPGA connected to PSOC port needs 1Kbytes data clock-by-clock once DMA is called. I believe there's  way to take clock out on PSOC port and connect it to downstram device. 

                 

              So the clock may be contineous, but data transiotions to occur only when DMA is called due to certain events in PSOC and downstream devices get 1K bytes of data for 1K clocks thereafter. 

                 

              Again, pardon my PSOC knowledge! - Is this possible architecture-wise?

                 

              Manish 

              • 4. Re: DMA to GPIO
                udayan.umapathi

                Hi,

                   
                      
                • It is not necessary to perform a Control Register to Pin Write operation. The output terminals of the Control register(which in this case is connected to Pins - GPIO) gets updated as soon as the DMA writes to the Control Register. Hence you will not be losing any clock cycle.
                •     
                • Yes it is possible to bring out a clock signal on one of the PSoC pins. Drag drop a clock component available in the Sytem Folder of Component Catalog. Connect it to a Digital Pin with Strong drive mode. See this      image.
                •     
                • The clock speed can be set to a desired value as shown      here.
                •    
                   

                 

                   

                -Udayan

                • 5. Re: DMA to GPIO
                  manish.ranade.2

                   Hi Udayan,

                     

                  I tried the DMA with ControlReg. It worked for me. 

                     

                  I have also sent system clock - 24MHz  out on another single-bit port.

                     

                  I have a PSOC board, I probbed the pins on Oscilloscope. 

                     

                  The pattern which I had loeaded was 64 samples of 0xaa, 0x55, 0xaa, 0x55 ...........

                     

                  As a result, I got a square wave output at POSOC pin. 

                     

                  But its period is a concern. For every clock of 24MHz  i should get fresh data sample, as result of DMA. 

                     

                  But thats not happening. A sample gets updated after 2 clocks. 

                     

                  I have attacghed waveform saved from Oscilloscope.

                     

                  BLUE signal is clock 

                     

                  Yellow signal is bit-0 of 8-bit data bus taken out of MEMORY-->DMA--ControlReg-->Port

                     

                  Whats' wrong in this?

                     

                  Beow is my main.c

                     

                  ---------------------------------------main.c---------------------------

                     

                   

                     

                  #include <device.h>

                     

                  #define BUFFER_SIZE 64

                     

                  #define TRUE 1

                     

                  #define FALSE 0

                     

                  uint8 Finished = 0; 

                     

                  /* Variable to store the status of DMA execution */

                     

                   /* The buffer that should be copied to RAM.  */

                     

                  CYCODE const uint8 SrcBuffer[BUFFER_SIZE] =

                     

                  {   

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55, 

                     

                      0xaa, 0x55, 0xaa, 0x55

                     

                  }; 

                     

                   

                     

                  CY_ISR(DmaDone)

                     

                  {

                     

                  Finished = 1;

                     

                  }

                     

                   

                     

                  void main()

                     

                  {

                     

                  uint8 MyTD;

                     

                  uint8 MyChannel;

                     

                   

                     

                  LCD_Display_Start();

                     

                  ISR_DMATransfer_Start();

                     

                  /* Perform dma in one burst.*/

                     

                  #if (defined(__C51__))

                     

                  /* PSoC 3 */

                     

                      #define DMA_SRC_BASE (CYDEV_FLS_BASE)

                     

                      #define DMA_DST_BASE (Control_Reg_1_ctrl_reg__CONTROL_REG)

                     

                  MyChannel = DMA_1_DmaInitialize (

                     

                  0,

                     

                  0, /* Automatically request carry out bursts.*/

                     

                  HI16(DMA_SRC_BASE), /* upper address bits are zero. */

                     

                  HI16(Control_Reg_1_ctrl_reg__CONTROL_REG)); /* upper address bits are zero. ????? */

                     

                  #else

                     

                  /* PSoC 5 */

                     

                      #define DMA_SRC_BASE (CYDEV_FLASH_BASE)

                     

                      #define DMA_DST_BASE (Control_Reg_1_ctrl_reg__CONTROL_REG)

                     

                  MyChannel = DMA_1_DmaInitialize (

                     

                  0,

                     

                        0,

                     

                  HI16(DMA_SRC_BASE), /* upper address bits are zero. */

                     

                        HI16(Control_Reg_1_ctrl_reg__CONTROL_REG) /*///// ????????????*/

                     

                  );

                     

                  #endif

                     

                   

                     

                  /* Get a Transaction Descriptor. */

                     

                  MyTD = CyDmaTdAllocate();

                     

                  if(MyTD == DMA_INVALID_TD)

                     

                  {

                     

                  /* Error Condition. */

                     

                  LCD_Display_Position(0,0);

                     

                  LCD_Display_PrintString("INIT NOT DONE");

                     

                  while(1)

                     

                  {

                     

                  /* Wait in an indefinite loop as the initialization could not be completed */

                     

                  ;

                     

                  }

                     

                  }

                     

                  /* Setup a TD. */

                     

                  /* Set TD to transfer 100 bytes with no next TD, */

                     

                  CyDmaTdSetConfiguration (

                     

                  MyTD,

                     

                  BUFFER_SIZE,

                     

                  DMA_INVALID_TD,

                     

                  TD_INC_SRC_ADR | DMA_1__TD_TERMOUT_EN

                     

                  );

                     

                   

                     

                  /* Copy from SrcBuffer to DesBuffer */

                     

                  CyDmaTdSetAddress (

                     

                  MyTD,

                     

                        (uint16)SrcBuffer,

                     

                        (uint16)Control_Reg_1_ctrl_reg__CONTROL_REG //// ??????

                     

                  );

                     

                   

                     

                  /* Associate the TD with the channel. */

                     

                  CyDmaChSetInitialTd(MyChannel, MyTD);

                     

                   

                     

                  /* Setup the Interrupt connected to the nrq terminal. */

                     

                  isr_1_SetVector(DmaDone);

                     

                  isr_1_SetPriority(7);

                     

                  isr_1_Enable();

                     

                   

                     

                  /* Enable the channel. */

                     

                  /* PreserveTds is set to 0 as the TD gets executed only once. */

                     

                  //MYR CyDmaChEnable(MyChannel, 0);

                     

                  CyDmaChEnable(MyChannel, TRUE); // 

                     

                   

                     

                  /* Request DMA action. */

                     

                  CyDmaChSetRequest(MyChannel, CPU_REQ);

                     

                  /* Wait for the interrupt to signal completion. */

                     

                  while(!Finished)

                     

                  ;

                     

                  /* We are done with the DMA and Interrupt components. */

                     

                  isr_1_Disable();

                     

                  DMA_1_DmaRelease();

                     

                  while(1);

                     

                   

                     

                  }

                     

                   

                     

                  /* [] END OF FILE */

                     
                       ----------------------------------------------------------------------------------------------------------------   
                  • 6. Re: DMA to GPIO
                    udayan.umapathi

                    Hi,

                       

                    I will work on this and get back to you.

                       

                    -Udayan

                    • 7. Re: DMA to GPIO
                      udayan.umapathi

                       Hi Manish,

                         

                      Can you archive and attach your project so that i can look in to it. I tried replicating your design. But looks like there is one ISR routine ISR_DMATransfer_Start which you have used. Can you add that part of code ?

                         

                      -Udayan

                      • 8. Re: DMA to GPIO
                        manish.ranade.2

                         Hi Udayan,

                           

                        My code is  the extract from different DMA example codes available on Cypress docs.

                           

                        There's nothing much being done in ISR.

                           

                        I have attached the archive here. 

                           

                        Thanks for your continued efforts to solve my problem.

                           

                         

                           

                        Manish

                        • 9. Re: DMA to GPIO
                          manish.ranade.2

                           For some reason, the archive didn't go through.

                             

                          Trying to send it again ...

                          • 10. Re: DMA to GPIO
                            manish.ranade.2

                             Hi, 

                               

                            Looks there's some problem on uploading project archive as size being ~2MB

                               

                            Hence now uploading a small zip file (GenFiles.zip) containing all "generated codes" and  the schematic view

                               

                            I hope this time it goes through!

                               

                             

                               

                            Manish 

                            • 11. Re: DMA to GPIO
                              udayan.umapathi

                              Hi Manish,

                                 

                              Can you e-mail the same to uday@cypress.com

                              • 12. Re: DMA to GPIO
                                udayan.umapathi

                                Hi,

                                   

                                Are you testing on this on PSoC3 device or PSoC5? Which Silicon revision are you using, ES2/ES3?

                                • 13. Re: DMA to GPIO
                                  manish.ranade.2

                                   Hi Uday,

                                     

                                  I am using PSOC5 

                                     

                                  The kit I am using is: CY8CKIT-001 PSoC® Development Kit   [http://www.cypress.com/?rID=37464]

                                     

                                   

                                     

                                  The PSOC chip is: CY8C5588AXI-060ES1

                                     

                                   

                                     

                                  Manish

                                  • 14. Re: DMA to GPIO
                                    gordon.rankin

                                    Uday,

                                       

                                    I need the reverse of this and was just playing around with PSOC Creator. So I can use a status register in sticky mode and then declare the clock input to latch the data, correct?

                                       

                                    My problem is that, how do I know when the DMA has read the status register so I can send and ACK back to the device sending the data so it knows it can send more data???

                                       

                                    Thanks

                                       

                                    Gordon

                                    1 2 Previous Next