stm32 fsmc synchronous mode

http://www.silica.com/designers-community/forum/view/topic/fsmc_in_synchrnous_mode.html

 

with FSMC_CLK = 2 HCLK cycles, throughput for write is about 32MBytes/s.

# STM32F2 runs at 120 MHz
# FSMC CLK = 60 MHz
#
NET "FSMC_CLK" TNM_NET = FSMC_CLK;
TIMESPEC TS_FSMC_CLK = PERIOD "FSMC_CLK" 60 MHz HIGH 50%;

# PlanAhead Generated physical constraints
NET "FSMC_A[0]" LOC = J13;
NET "FSMC_A[1]" LOC = H13;
NET "FSMC_A[2]" LOC = H15;
NET "FSMC_A[3]" LOC = H14;
NET "FSMC_A[4]" LOC = G13;
NET "FSMC_A[5]" LOC = G14;
#NET "FSMC_A[6]" LOC = C17;
#NET "FSMC_A[7]" LOC = E16;
#NET "FSMC_A[8]" LOC = E18;
#NET "FSMC_A[9]" LOC = D17;
#NET "FSMC_A[10]" LOC = G16;
#NET "FSMC_A[11]" LOC = F14;
#NET "FSMC_A[12]" LOC = T18;
#NET "FSMC_A[13]" LOC = U18;
#NET "FSMC_A[14]" LOC = H12;
#NET "FSMC_A[15]" LOC = K16;
#NET "FSMC_A[16]" LOC = L17;
#NET "FSMC_A[17]" LOC = K18;
#NET "FSMC_A[18]" LOC = P18;
#NET "FSMC_A[19]" LOC = T17;
#NET "FSMC_A[20]" LOC = U17;
#NET "FSMC_A[21]" LOC = L13;
#NET "FSMC_A[22]" LOC = M13;
#NET "FSMC_A[23]" LOC = P16;
#NET "FSMC_A[24]" LOC = M16;
#NET "FSMC_A[25]" LOC = M18;

NET "FSMC_D[0]" LOC = N17;
NET "FSMC_D[1]" LOC = P17;
NET "FSMC_D[2]" LOC = L15;
NET "FSMC_D[3]" LOC = K13;
NET "FSMC_D[4]" LOC = F18;
NET "FSMC_D[5]" LOC = F17;
NET "FSMC_D[6]" LOC = F16;
NET "FSMC_D[7]" LOC = G18;
NET "FSMC_D[8]" LOC = F15;
NET "FSMC_D[9]" LOC = H18;
NET "FSMC_D[10]" LOC = H17;
NET "FSMC_D[11]" LOC = J16;
NET "FSMC_D[12]" LOC = J18;
NET "FSMC_D[13]" LOC = L18;
NET "FSMC_D[14]" LOC = K17;
NET "FSMC_D[15]" LOC = N18;

NET "FSMC_CLK" LOC = K15;
NET "FSMC_NBL[0]" LOC = N16 | PULLUP;
NET "FSMC_NBL[1]" LOC = P15 | PULLUP;
#NET "FSMC_NE[1]" LOC = L16 | PULLUP;
NET "FSMC_NE[2]" LOC = L12 | PULLUP;
#NET "FSMC_NE[3]" LOC = N15 | PULLUP;
#NET "FSMC_NE[4]" LOC = N14 | PULLUP;
NET "FSMC_NL" LOC = L14 | PULLUP;
NET "FSMC_NOE" LOC = H16 | PULLUP;
NET "FSMC_NWAIT" LOC = M14;
NET "FSMC_NWE" LOC = K12 | PULLUP;

# PlanAhead Generated IO constraints
NET "FSMC_A[*]" IOSTANDARD = LVCMOS33;
NET "FSMC_CLK" IOSTANDARD = LVCMOS33;
NET "FSMC_D[*]" IOSTANDARD = LVCMOS33 | SLEW = FAST;
NET "FSMC_NBL[0]" IOSTANDARD = LVCMOS33;
NET "FSMC_NBL[1]" IOSTANDARD = LVCMOS33;
NET "FSMC_NE[*]" IOSTANDARD = LVCMOS33;
NET "FSMC_NL" IOSTANDARD = LVCMOS33;
NET "FSMC_NOE" IOSTANDARD = LVCMOS33;
NET "FSMC_NWAIT" IOSTANDARD = LVCMOS33;
NET "FSMC_NWE" IOSTANDARD = LVCMOS33;

 

library IEEE;

use IEEE.std_logic_1164.all;
--use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity fsmc is
port (
-- clk_25mhz : in STD_LOGIC;
FSMC_A : in STD_LOGIC_VECTOR(5 downto 0); --25
FSMC_D : inout STD_LOGIC_VECTOR(15 downto 0);
FSMC_NBL : in STD_LOGIC_VECTOR(1 downto 0);
FSMC_NE : in STD_LOGIC_VECTOR(2 downto 2); -- 4 downto 1
FSMC_NL : in STD_LOGIC;
FSMC_NOE : in STD_LOGIC;
FSMC_NWAIT : out STD_LOGIC;
FSMC_NWE : in STD_LOGIC;
FSMC_CLK : in STD_LOGIC;
);
end fsmc;
architecture Behavioral of fsmc is
constant memsize : integer := 6; -- 2^6 = 64 bytes
signal NE : std_logic;
signal ADDR : std_logic_vector ( memsize-1 downto 0);
signal rdADDR : std_logic_vector ( memsize-1 downto 0);
signal phase : integer range 0 to 32 := 0;
signal FSMC_dout : std_logic_vector(15 downto 0);
type memory_type is array (0 to ((2**memsize) - 1)) of std_logic_vector(7 downto 0);
signal mbuf_hi : memory_type;
signal mbuf_lo : memory_type;
attribute ram_style : string;
attribute ram_style of mbuf_hi : signal is "block";
attribute ram_style of mbuf_lo : signal is "block";
begin
FSMC_NWAIT <= '1'; -- Wait states not used
NE <= FSMC_NE(2); -- bank 2 chipselect
LED <= "11"; --(not green) & (not red);
FSMC_D <= FSMC_dout when FSMC_NOE = '0' else (others => 'Z');
process (FSMC_CLK)
begin
if (FSMC_CLK'event and FSMC_CLK = '1') then
if (NE = '0') then
if (FSMC_NL = '0') then -- access starts with NL (NADVL) low
phase <= 0;
else
phase <= phase + 1; -- increment clock phase
end if;
if (FSMC_NL = '0') then -- access starts with NL (NADVL) low
ADDR <= FSMC_A((memsize-1) downto 0);
end if;
if ((FSMC_NL = '1') and (FSMC_NWE = '0') and (phase > 1)) then
if FSMC_NBL(1) = '0' then
mbuf_hi(conv_integer(ADDR((memsize-1) downto 0))) <= FSMC_D(15 downto 8);
end if;
if FSMC_NBL(0) = '0' then
mbuf_lo(conv_integer(ADDR((memsize-1) downto 0))) <= FSMC_D(7 downto 0);
end if;
ADDR <= ADDR + 1;
end if;
end if;
end if; -- rising edge, WRITE
if (FSMC_CLK'event and FSMC_CLK = '0') then
if (phase = 0) then
rdADDR <= ADDR;
elsif (NE = '0') then
FSMC_dout(15 downto 8) <= mbuf_hi(conv_integer(rdADDR((memsize-1) downto 0)));
FSMC_dout(7 downto 0) <= mbuf_lo(conv_integer(rdADDR((memsize-1) downto 0)));
if (FSMC_NOE = '0') then
rdADDR <= rdADDR + 1;
end if;
end if;
end if; -- falling edge, READ
end process;
end Behavioral;

 

 

void SystemInit_ExtMemCtl(void)
{
/*-- GPIOs Configuration -----------------------------------------------------*/
/*
+-------------------+--------------------+------------------+------------------+
+ SRAM pins assignment +
+-------------------+--------------------+------------------+------------------+
| PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
| PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
| PD4 <-> FSMC_NOE | PE7 <-> FSMC_D4 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
| PD5 <-> FSMC_NWE | PE8 <-> FSMC_D5 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
| PD8 <-> FSMC_D13 | PE9 <-> FSMC_D6 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
| PD9 <-> FSMC_D14 | PE10 <-> FSMC_D7 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
| PD10 <-> FSMC_D15 | PE11 <-> FSMC_D8 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
| PD11 <-> FSMC_A16 | PE12 <-> FSMC_D9 | PF13 <-> FSMC_A7 |------------------+
| PD12 <-> FSMC_A17 | PE13 <-> FSMC_D10 | PF14 <-> FSMC_A8 | 
| PD14 <-> FSMC_D0 | PE14 <-> FSMC_D11 | PF15 <-> FSMC_A9 | 
| PD15 <-> FSMC_D1 | PE15 <-> FSMC_D12 |------------------+
+-------------------+--------------------+
PD3 <-> FSMC_CLK
PD6 <-> FSMC_NWAIT
PB7 <-> FSMC_NL (NADVL)
*/
/* Enable GPIOB, GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR = 0x0000007a; // /78

/* Connect PBx pins to FSMC Alternate function */
GPIOB->AFR[0] = 0xc0000000; 
GPIOB->AFR[1] = 0x00000000;
/* Configure PBx pins in Alternate function mode */ 
GPIOB->MODER = 0x00008000; 
/* Configure PBx pins speed to 100 MHz */ 
GPIOB->OSPEEDR = 0x0000c000; 
/* Configure PBX pins Output type to push-pull */ 
GPIOB->OTYPER = 0x00000000;
/* No pull-up, pull-down for PBx pins */ 
GPIOB->PUPDR = 0x00000000;



/* Connect PDx pins to FSMC Alternate function */
GPIOD->AFR[0] = 0x0cccc0cc; // 0x00cc00cc
GPIOD->AFR[1] = 0xcc0ccccc;
/* Configure PDx pins in Alternate function mode */ 
GPIOD->MODER = 0xa2aa2a8a; // 0xa2aa0a0a
/* Configure PDx pins speed to 100 MHz */ 
GPIOD->OSPEEDR = 0xf3ff3fcf; // 0xf3fff0f0f
/* Configure PDx pins Output type to push-pull */ 
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */ // PD6 NWAIT pullup
GPIOD->PUPDR = 0x00001000;

/* Connect PEx pins to FSMC Alternate function */
GPIOE->AFR[0] = 0xc00000cc;
GPIOE->AFR[1] = 0xcccccccc;
/* Configure PEx pins in Alternate function mode */ 
GPIOE->MODER = 0xaaaa800a;
/* Configure PEx pins speed to 100 MHz */ 
GPIOE->OSPEEDR = 0xffffc00f;
/* Configure PEx pins Output type to push-pull */ 
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */ 
GPIOE->PUPDR = 0x00000000;

/* Connect PFx pins to FSMC Alternate function */
GPIOF->AFR[0] = 0x00cccccc;
GPIOF->AFR[1] = 0xcccc0000;
/* Configure PFx pins in Alternate function mode */ 
GPIOF->MODER = 0xaa000aaa;
/* Configure PFx pins speed to 100 MHz */ 
GPIOF->OSPEEDR = 0xff000fff;
/* Configure PFx pins Output type to push-pull */ 
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */ 
GPIOF->PUPDR = 0x00000000;

/* Connect PGx pins to FSMC Alternate function */
GPIOG->AFR[0] = 0x00cccccc;
GPIOG->AFR[1] = 0x000000c0;
/* Configure PGx pins in Alternate function mode */ 
GPIOG->MODER = 0x00080aaa;
/* Configure PGx pins speed to 100 MHz */ 
GPIOG->OSPEEDR = 0x000c0fff;
/* Configure PGx pins Output type to push-pull */ 
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */ 
GPIOG->PUPDR = 0x00000000;

/*-- FSMC Configuration ------------------------------------------------------*/
/* Enable the FSMC interface clock */
RCC->AHB3ENR = 0x00000001;

/* Configure and enable Bank1_SRAM2 */ 
FSMC_Bank1->BTCR[2] = 0x00081115; // 0x00001015
// CBURSTRW = 1
// ACYCWAIT = 0
// EXTMOD = 0
// WAITEN = 0
// WREN = 1
// WAITCFG = 0
// WRAPMOD = 0
// WAITPOL = 0
// BURSTEN = 1
// FACCEN = 0
// MWID = 01 (16 bits)
// MTYP = 01 (PSRAM)
// MUXEN = 0 (Non-multiplexed)
// MBKEN = 1

FSMC_Bank1->BTCR[3] = 0x00110400; // 0x00010400
// ACCMOD = 00 (Access mode A)
// DATLAT = 0 (2 CLK cycles)
// CLKDIV = 1 (2 HCLK periods)
// BUSTURN = 1 (1 HCLK added)
// DATAST = 4 (data phase 4 HCLK cycles)
// ADDHLD = 0 (Reserved)
// ADDSET = 0 (0 HCLK cycles)


FSMC_Bank1E->BWTR[2] = 0x0fffffff;

// BTCR 0 = BCR1
// BTCR 1 = BTR1
// BTCR 2 = BCR2
// BTCR 3 = BTR2
// BTCR 4 = BCR3
// BTCR 5 = BTR3
// BTCR 6 = BCR4
// BTCR 7 = BTR4

/*
Bank1_SRAM2 is configured as follow:

p.FSMC_AddressSetupTime = 0;
p.FSMC_AddressHoldTime = 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_DataAddressMux = FSMC_DataAddressMux_Disable;
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_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
*/

}

 

 

Attached file contains function SystemInit_ExtMemCtl which i did modify.

Uncomment this line:

#define DATA_IN_ExtSRAM

I added following pins

PD3 <-> FSMC_CLK
PD6 <-> FSMC_NWAIT
PB7 <-> FSMC_NL (NADVL)

And then enabled CBURSTRW, BURSTEN, set CLKDIV=1

posted @ 2012-03-25 14:47  IAmAProgrammer  阅读(1668)  评论(0编辑  收藏  举报