cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F2, FSMC, SSD1963 Performance

mfranklin
Associate III
Posted on June 12, 2012 at 02:43

I've recently created a prototype with a STM32F2 and a Solomon Systech SSD1963 interfaced via the FSMC (Resolution: 800 x 480).  I've succeeded in getting things displayed on the screen, but I'm a little disappointed in performance.  (Please note that I'm only referring to the amount of time it takes to write data to the SSD1963's frame buffer from the STM32F2, not the refresh rate of the LCD).  I've only been able to get about 3 FPS and I was hoping for something in the teens. 

Are my expectations too high?  Please share your experience and offer your advice.

Here's my FSMC init code.

//--- FSMC Configuration -----------------------------------------------------

  //FSMC Initialization

  FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;

  FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;

 

  // Enable the FSMC Clock

  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

   

  FSMC_NORSRAMDeInit(FSMC_Bank1_NORSRAM1);

 

  FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime      = 0;     // 1ns

  FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime       = 1;     // 2ns

  FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime         = 1;     // 4ns

  FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode            = FSMC_AccessMode_B; //?? don't know yet

 

  FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0;     // Only used with NOR Flash

  FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision           = 1;     // Not used for Nor or SRAM

  FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency           = 0;     // Don't care with Nor or SRAM

  FSMC_NORSRAMInitStructure.FSMC_Bank                  = FSMC_Bank1_NORSRAM1;

  FSMC_NORSRAMInitStructure.FSMC_MemoryType            = FSMC_MemoryType_NOR;

  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth       = FSMC_MemoryDataWidth_16b;

  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;

  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct     = &FSMC_NORSRAMTimingInitStructure;

  FSMC_NORSRAMInitStructure.FSMC_WriteOperation        = FSMC_WriteOperation_Enable;

 

  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_Low;           // Only valid for flash memory in burst mode (just default)

  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive      = FSMC_WaitSignalActive_BeforeWaitState; // Only valid for burst memories (just default)

  FSMC_NORSRAMInitStructure.FSMC_WaitSignal            = FSMC_WaitSignal_Disable;               // Only valid for flash memory in burst mode (just default)

  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode          = FSMC_ExtendedMode_Disable;             // Don't know yet

  FSMC_NORSRAMInitStructure.FSMC_WriteBurst            = FSMC_WriteBurst_Disable;               // Don't know yet

  FSMC_NORSRAMInitStructure.FSMC_WrapMode              = FSMC_WrapMode_Disable;                 // Don't know yet

  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux        = FSMC_DataAddressMux_Disable;           // Don't know yet

  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Disable;          // Don't know yet

 

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

 

  // Enable FSMC Bank1_SRAM Bank

  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); 

Thanks

#ssd1963-lcd #lmgtfy #st32f2-fsmc #ssd1963-stm32f4-lcd-fsmc
12 REPLIES 12
himanshusharma
Associate II
Posted on June 18, 2014 at 13:28

Hi Mike,

How far u are now can you post your code here?

Posted on June 18, 2014 at 14:26

Consider that this is a 2 year old thread, and the OP has moved on..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mfranklin
Associate III
Posted on September 02, 2014 at 03:33

Sorry for not being more responsive. I have, for the most part, moved on, but I am able to get much better results now. I don't remember what the exact change was as it was so long ago, but here's the essential driver configuration code:

void
FSMC::EnableBank(
const
SRAMBank bank, 
const
uint32_t addressSetupTime, 
const
uint32_t addressHoldTime, 
const
uint32_t dataSetupTime, 
const
uint32_t busTurnaroundDuration)
{
GPIO& gpio = GPIO::GetInstance();
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;
switch
(bank)
{
case
SRAMBank::_1:
gpio.AlternateFunction(GPIO::Port::D, GPIO::Pin::_7, GPIO::AltFunction::FSMC); 
// NE1
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; 
//?? don't know yet
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
break
;
case
SRAMBank::_2:
gpio.AlternateFunction(GPIO::Port::G, GPIO::Pin::_9, GPIO::AltFunction::FSMC); 
// NE2
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; 
//?? don't know yet
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
break
;
case
SRAMBank::_3:
gpio.AlternateFunction(GPIO::Port::G, GPIO::Pin::_10, GPIO::AltFunction::FSMC); 
// NE3, CS#
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_B; 
//?? don't know yet
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
break
;
default
:
break
;
}
uint32_t stdPeriphBank = (uint32_t)bank * 2;
FSMC_NORSRAMDeInit(stdPeriphBank);
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = addressSetupTime;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = addressHoldTime;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = dataSetupTime;
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = busTurnaroundDuration; 
// Only used with NOR Flash
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0; 
// Not used for Nor or SRAM
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0; 
// Don't care with Nor or SRAM
FSMC_NORSRAMInitStructure.FSMC_Bank = stdPeriphBank;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; 
// Only valid for flash memory in burst mode (just default)
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; 
// Only valid for burst memories (just default)
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; 
// Only valid for flash memory in burst mode (just default)
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(stdPeriphBank, ENABLE);
}
//Enable FSMC 
FSMC::GetInstance().EnableBank(FSMC::SRAMBank::_3, 12, 24, 24, 0); 
// GPU Clock
GPIO::GetInstance().AlternateFunction(GPIO::Port::A, GPIO::Pin::_8, GPIO::AltFunction::MCO); 
RCC_MCO1Config(RCC_MCO1Source_HSI, RCC_MCO1Div_2);
//---- Do a hard reset -------------------------------------------------------
DigitalOutput& hardReset = DigitalOutput::GetInstance(DigitalOutput::Channel::LCDReset);
hardReset.Low();
Stopwatch::DelayMilliseconds(100);
hardReset.High();
Stopwatch::DelayMilliseconds(100);
//--- PLL Configuration ------------------------------------------------------
// VCO = Reference Frequency*(M+1)
// PLL Frequency = VCO/(N+1)
// * Note : 250MHz < VCO < 800MHz
//
// Example) Reference Frequency = 8MHz
// PLL Frequency = 100MHz
//
// 100MHz = 8MHz*(49+1)/(3+1)
// => M = 49, N = 3
SendCommand(SSD1963::Command::SET_PLL_MN);
SendData16(50 - 1); 
//M 8MHz times 60
SendData16(4 - 1); 
//N divided by 4 = 100
SendData16(0x04); 
//Make M and N Effective
//Turn On PLL
SendCommand(SSD1963::Command::SET_PLL);
SendData16(0x01); 
//Enable PLL
Stopwatch::DelayMilliseconds(5);
//Lock PLL
SendCommand(SSD1963::Command::SET_PLL);
SendData16(0x03); 
//Set as system clock, while keeping PLL enabled
Stopwatch::DelayMilliseconds(5);
//---- Do a soft reset -------------------------------------------------------
SendCommand(SSD1963::Command::SOFT_RESET);
Stopwatch::DelayMilliseconds(5);
//Full Speed
FSMC::GetInstance().EnableBank(FSMC::SRAMBank::_3, 0, 0, 0, 0); 
DigitalInput::GetInstance(DigitalInput::Channel::GPURefresh).SetInterruptEdge(MoaTouch::Edge::Falling);

I'm using C++, and have created my own API for the FSMC and the SS1963, but I hope you can glean my configuration from the code above. I still don't know whether FSMC_AccessMode_B and FSMC_MemoryType_NOR is correct, but it works. If you know, please let me know and provide justification. Also, you'll notice that I have configured the memory settings very slow for setup, but then enable full-speed at the end. I had to do this or I'd get errors in my configuration (I don't remember specifically what they were, sorry). I don't have any benchmark numbers, because I'm using external SRAM as a temporary frame buffer and I'm synchronizing SRAM-to-SSD1963 flushes with the vertical refresh, so it's not an ''immediate mode'' type of setup. But I am able to achieve acceptable performance for my application. We're exploring the STM32F4 MCUs that have a built-in LCD controller now, and hopefully we'll be able to make a more efficient architecture and improve performance, but I don't have any code yet for that. I'm afraid it would be too much of a burden for me to put my schematics in a format for the public, so I can't release those to you. I'm sorry! Good luck! ...and thanks to those on this forum that responded to my original post.