# Porting an STM32 PSRAM driver

I have an STM32F2 development board that came with a PSRAM (IS61WV10248BLL), and I have a custom board with a different PSRAM (MT45W8MW16BGX).

I have managed to get the PSRAM on the development board to work fine. However, I'm having problems driving the new PSRAM on my custom board. The main difference I see between the two memories is that the new PSRAM has more address pins. I have made sure to properly initialise all my clocks and GPIO pins, and I have checked that the ARM memory controller has reasonable settings.

What difference between the two PSRAMs could cause my old driver to go wrong?

Below is the memory controller configuration I am currently using:

  p.FSMC_AddressSetupTime = 0;
p.FSMC_DataSetupTime = 4;
p.FSMC_BusTurnAroundDuration = 1;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_A;

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
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_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

-
you gotto look at timings.. SRAM/NOR-Flash chip-select timing registers 1..4 (FSMC_BTR1..4) page 1249 in my F2 reference manual.. The answer is there in those 2 registers. –  Ktc Jul 3 '12 at 3:29
also, there is an excel sheet from ST web site that allows you to configure clocks.. neat tool. You need to fiddle with that since most of the data in the register I mention above tied to the system clock etc. so you must get that system clock details right. don't use the examples generate your own system config file using the excel tool –  Ktc Jul 3 '12 at 3:31
@Ktc: The only clock configuration tool I found is for the systems clocks, not the FSMC timings. Am I missing something? –  Randomblue Jul 4 '12 at 8:01
no you are not.. FSMC timing highly tied to system clock diagrams. You make sure you run that system clock tool first and make your FSMC timing as slow as possible. once you do this do a simple read write. if you are able to read write, increase the speed, you will hit a spot that the ram cannot catch up with your timing, come back 30% and that is your optimal timing. –  Ktc Jul 4 '12 at 8:54
if you cannot read even the speed is slow, I have two suggestion. Buy a faster memory and replace with the one on your board, see what happens. If this fails, the problem is in the hardware, probably your schematic wrong or layout has an issue. –  Ktc Jul 4 '12 at 8:55
show 1 more comment

I've just had a very quick look at the datasheets, and I can see that the Micron RAM has much higher access times than the ISSI RAM. Depending on how fast your MCU is running, you might thus need to insert a couple of waitstates when accessing it.

Have a look at the STM32 manual, which has a couple of helpful figures for determining where to insert waitstates and how many (this is done through the FSMC_AddressSetupTime, FSMC_AddressHoldTime and FSMC_DataSetupTime, amonst others).

-
Thanks. I've now double checked every single timing configuration. It's still not working. When I make a write and then read right after, the ARM crashes. I don't know how to debug this problem. –  Randomblue Jul 4 '12 at 10:09

For that PSRAM (MT45W8MW16BGX-701IT ), I'm using these values

p.FSMC_AddressSetupTime = 3;
p.FSMC_DataSetupTime = 6;
p.FSMC_BusTurnAroundDuration = 1;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_A;

FSMC_NORSRAMStructInit(&FSMC_NORSRAMInitStructure);

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
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_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;