- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Labels:
-
PSoC 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See the image available here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I will work on this and get back to you.
-Udayan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For some reason, the archive didn't go through.
Trying to send it again ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Are you testing on this on PSoC3 device or PSoC5? Which Silicon revision are you using, ES2/ES3?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One thing I noticed about your code is that the base address for the control register is set wrong. It should be like (copy from my own code):
#define DMA_DIG_SRC_BASE (CYDEV_PERIPH_BASE)
Chan = DMA_DIG_DmaInitialize(DMA_DIG_BYTES_PER_BURST, DMA_DIG_REQUEST_PER_BURST,
HI16(DMA_DIG_SRC_BASE), HI16(DMA_DIG_DST_BASE));
Your code used HI16(ControlReg), which is maybe wrong for PSoC5 (for PSoC3 I think it still might be correct).
Did you look at your DMA priority levels? If your DMA has a priority other than 0 or 1, it gets only 50% of bus bandwidth (or even less).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Wavelength: no, sticky mode would be wrong. In this mode, when an input goes high than the registeres marks it as high - even when it goes low afterwards. I think you want to look a the DFlip Flop. It can be used with a 8bit bus width, and can be used to capture the input state as you want.
If you have an external request, I think a simple state machine built with a LUT would be enough.