2012-06-11 05:43 PM
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-fsmc2014-06-18 04:28 AM
Hi Mike,
How far u are now can you post your code here?2014-06-18 05:26 AM
Consider that this is a 2 year old thread, and the OP has moved on..
2014-09-01 06:33 PM
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.