2014-04-14 12:23 PM
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,2014-04-14 01:05 PM
- use hardware
- use assembler - don't have unrealistic expectations JW2014-04-14 01:07 PM
could you give me hint about hardware ?
2014-04-14 01:59 PM
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. JW2014-04-14 02:07 PM
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 :(2014-04-14 02:32 PM
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.2014-04-14 02:39 PM
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.
2014-04-14 02:54 PM
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 ...2014-04-14 04:35 PM
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.2014-04-15 12:32 AM
so the results:
HalfWord (16bit) ... 8192 bytes copied in 452uSByte (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