cancel
Showing results for 
Search instead for 
Did you mean: 

data transfer speeds

developer2
Senior
Posted on April 14, 2014 at 21:23

Hi all, 

i'm dissapointed from transfer speeds on STM32F407 @ 168MHz core,

i'm measuring roughly 10.7MHz using FSMC with the code:

runTIM_stoptime();

do

{

  hh=fsmc_read( 0 );

}

while( (ui32--) > 0 );

stopTIM_stoptime();

USARTdebug_puthex_32bit( hh );

and with using DMA copying from GPIO full 16bit i'm measuring 11 MHz,

please somebody help me, 

is there a faster way how to transfer data ?

configuration of FSMC: 

  p.FSMC_AddressSetupTime = 0;

  p.FSMC_AddressHoldTime = 0;

  p.FSMC_DataSetupTime = 4;

  p.FSMC_BusTurnAroundDuration = 0;

  p.FSMC_CLKDivision = 0;

  p.FSMC_DataLatency = 0;

  p.FSMC_AccessMode = FSMC_AccessMode_B;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;

  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;

  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;

  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;

  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;

  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;

  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;

  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;

  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;

  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Disable;

  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;

  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;

  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;

  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;

  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

Kind regards, 

9 REPLIES 9
Posted on April 14, 2014 at 22:05

- use hardware

- use assembler

- don't have unrealistic expectations

JW

developer2
Senior
Posted on April 14, 2014 at 22:07

could you give me hint about hardware ? 

Posted on April 14, 2014 at 22:59

Start with a LA. Check whether the timing conforms to your settings, and fine-tune it to the connected device (from other thread I understand it's supposed to be an ADC - which model namely?).

In the other thread Clive already gave you sound recommendations - use the camera interface, or add a FIFO.

JW

developer2
Senior
Posted on April 14, 2014 at 23:07

well , i already did fine-tuning , there is : FSMC_DataSetupTime = 4; 

there is only value of ''3'' lowest fastest value so i put ''4'', 

my configuration is A/D converter at 40MSPS with 16bit data width and with FPGA as FIFO, 

but if i will receive samples at 11MHz i will loose too many frames between and i can't use idea of triggering FIFO like it is in oscilloscopes :( 

Posted on April 14, 2014 at 23:32

So what exactly does the code for fsmc_read( 0 ); look like?

uint32_t *p = (uint32_t *)0x60000000; // or whatever the base

Writing 32bit will result in two back-to-back transfers at 16-bit

while(i--)

  *p = 0;

In assembler STM would work quite well also.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 14, 2014 at 23:39

And what exactly is going to happen to all this data? At some point you're going to run out of space, or processing power.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
developer2
Senior
Posted on April 14, 2014 at 23:54

the translated code looks like this: 

 232:main.c        ****   do

 233:main.c        ****   {

 234:main.c        ****     hh=fsmc_read( 0 );

 278                            .loc 1 234 0

 279 002c 4FF0C042              mov     r2, #1610612736

 280                    .LVL5:

 281                    .L6:

 282                            .loc 1 234 0 is_stmt 0 discriminator 1

 283 0030 1488                  ldrh    r4, [r2, #0]

 284 0032 A4B2                  uxth    r4, r4

 285                    .LVL6:

 235:main.c        ****   }

 236:main.c        ****   while( (ui32--) > 0 );

 286                            .loc 1 236 0 is_stmt 1 discriminator 1

 287 0034 03F1FF33              add     r3, r3, #-1

 288                    .LVL7:

 289 0038 B3F1FF3F              cmp     r3, #-1

 290 003c F8D1                  bne     .L6

... so i thought that it's optimised mostly as it can be to do fastest reading ... so in your opinion is it fastest as it can be ? 

is there possibility to use DMA to get data into embedded RAM faster ? 

maybe transfers between AHB2 or AHB1 is slowering the DMA and AHB3 may go faster ...

so configuration will be FPGA into FSMC and from FSMC into embedded RAM using DMA, and processor will be free for operations ... 

Posted on April 15, 2014 at 01:35

Well I could remove half the instructions from the loop, and read 32-bit (16-bit pairs), so I'd imagine that would make a fairly dramatic difference. Using LDM I could unwrap the loop somewhat too.

If your destination is internal RAM, then yes a M2M (Memory to Memory) DMA transfer would be the way to go, nominally the inverse of DMA to FSMC-LCD painting the frame buffer.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
developer2
Senior
Posted on April 15, 2014 at 09:32

so the results: 

HalfWord (16bit) ... 8192 bytes copied in 452uS

Byte (8bit) ... 8192 bytes copied in 445uS

... it's around 18MHz ... am i right ?

it's not really full speed as i need but it's better then 11MHz ... 

with configuration of DMA:

  DMA_InitStructure.DMA_Channel = DMA_Channel_0;

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)FPGA_BASE;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC_Buffer_Main;

  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;

  DMA_InitStructure.DMA_BufferSize = (uint32_t)8192;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //HalfWord;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

  DMA_Init( DMA2_Stream0, &DMA_InitStructure);

Kind regards