Skip to main content
developer2
Senior
April 14, 2014
Question

data transfer speeds

  • April 14, 2014
  • 9 replies
  • 1497 views
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, 

    This topic has been closed for replies.

    9 replies

    waclawek.jan
    Super User
    April 14, 2014
    Posted on April 14, 2014 at 22:05

    - use hardware

    - use assembler

    - don't have unrealistic expectations

    JW

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

    could you give me hint about hardware ? 

    waclawek.jan
    Super User
    April 14, 2014
    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
    April 14, 2014
    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 :( 

    Tesla DeLorean
    Guru
    April 14, 2014
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    April 14, 2014
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    developer2
    Senior
    April 14, 2014
    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 ... 

    Tesla DeLorean
    Guru
    April 14, 2014
    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    developer2
    Senior
    April 15, 2014
    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