2014-04-25 03:10 AM
Hi all,
I would like to interface a NOR Flash using the FSMC. However I cannot find a tutorial how to compute ADDSET and DATAST. I found application note AN2784 but it is forSTM32F10xxx. Also looking at the values and formulas provided in the NOR Flash example, it seems some calculation mistakes have been made, so it is unreliable. The NOR Flash I will be interfacing is the SPANSIONS29GL128S. Any help will be greatly appreciated. If I use the formulas provided in AN2784, my results are as follows: // Configure then enable NOR Flash // tHCLK = 6 ns, tWC = 60 ns, tWP = 25 ns, // Formula 1: DATAST = tWP / HCLK = 25 / 6 ~= 4 // Formula 2: ( (ADDSET + 1) + (DATAST + 1) ) × tHCLK = max (tWC) // so (ADDSET + 1) = 60 / 6 - ( 5 + 1 ) -> ADDSET = 4 However, using those values read wrong values (0s everywhere). When I use ADDSET = 0 and DATAST = 17 I get good readings. The reason I used 17 for DATAST is because theS29GL128S tACC is 100 ns and my tHCLK is 6, so 17 x 6 is . Please help.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 | PE2 <-> FSMC_A23 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
| PD5 <-> FSMC_NWE | PE3 <-> FSMC_A19 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
| PD6 <-> FSMC_NWAIT | PE4 <-> FSMC_A20 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
| PD7 <-> FSMC_NE1 | PE5 <-> FSMC_A21 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
| PD8 <-> FSMC_D13 | PE6 <-> FSMC_A22 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
| PD9 <-> FSMC_D14 | PE7 <-> FSMC_D4 | PF13 <-> FSMC_A7 | PG10 <-> FSMC_NE3 |
| PD10 <-> FSMC_D15 | PE8 <-> FSMC_D5 | PF14 <-> FSMC_A8 | PG12 <-> FSMC_NE4 |
| PD11 <-> FSMC_A16 | PE9 <-> FSMC_D6 | PF15 <-> FSMC_A9 | PG13 <-> FSMC_A24 |
| PD12 <-> FSMC_A17 | PE10 <-> FSMC_D7 |------------------+ PG14 <-> FSMC_A25 |
| PD13 <-> FSMC_A18 | PE11 <-> FSMC_D8 | +-------------------+
| PD14 <-> FSMC_D0 | PE12 <-> FSMC_D9 |
| PD15 <-> FSMC_D1 | PE13 <-> FSMC_D10 |
| | PE14 <-> FSMC_D11 |
| | PE15 <-> FSMC_D12 |
+---------------------+----------------------+--------------------+--------------------+
*/
uint32_t DATAST;
uint32_t ADDSET;
// Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock
RCC->AHB1ENR = (RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN);
// Connect PDx pins to FSMC Alternate function
GPIOD->AFR[0] = 0xcccc00cc;
GPIOD->AFR[1] = 0xcccccccc;
GPIOD->MODER = 0xaaaaaa0a; // Configure PDx pins in Alternate function mode
GPIOD->OSPEEDR = 0xaaaaaa0a; // Configure PDx pins speed to 50 MHz
GPIOD->OTYPER = 0x00000000; // Configure PDx pins Output type to push-pull
GPIOD->PUPDR = 0x00000000; // No pull-up, pull-down for PDx pins
// Connect PEx pins to FSMC Alternate function
GPIOE->AFR[0] = 0xcccccccc;
GPIOE->AFR[1] = 0xcccccccc;
GPIOE->MODER = 0xaaaaaaaa; // Configure PEx pins in Alternate function mode
GPIOE->OSPEEDR = 0xaaaaaaaa; // Configure PEx pins speed to 50 MHz
GPIOE->OTYPER = 0x00000000; // Configure PEx pins Output type to push-pull
GPIOE->PUPDR = 0x00000000; // No pull-up, pull-down for PEx pins
// Connect PFx pins to FSMC Alternate function
GPIOF->AFR[0] = 0x00cccccc;
GPIOF->AFR[1] = 0xcccc0000;
GPIOF->MODER = 0xaa000aaa; // Configure PFx pins in Alternate function mode
GPIOF->OSPEEDR = 0xaa000aaa; // Configure PFx pins speed to 50 MHz
GPIOF->OTYPER = 0x00000000; // Configure PFx pins Output type to push-pull
GPIOF->PUPDR = 0x00000000; // No pull-up, pull-down for PFx pins
// Connect PGx pins to FSMC Alternate function
GPIOG->AFR[0] = 0x00cccccc;
GPIOG->AFR[1] = 0x0ccc0cc0;
GPIOG->MODER = 0x2a280aaa; // Configure PGx pins in Alternate function mode
GPIOG->OSPEEDR = 0x2a280aaa; // Configure PGx pins speed to 50 MHz
GPIOG->OTYPER = 0x00000000; // Configure PGx pins Output type to push-pull
GPIOG->PUPDR = 0x00000000; // No pull-up, pull-down for PGx pins
//-- FSMC Configuration ------------------------------------------------------*/
// Enable the FSMC interface clock
RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN;
//NE1 = CS0 = SRAM
//NE2 = CS1 = FLASH
//NE3 = CS2 = Not used
//NE4 = CS3 = Ethernet
//Note: HCLK cycle = 1/168MHz = 6 ns, use it to adjust memory transaction times
// Configure then enable SRAM (Mode 1)
// tHCLK = 6 ns, tWC = 10 ns, tPWE1 = 7 ns, tAA = 10 ns, tsu(Data_NE) = 10 ns, tv(A_NE) = 4.5 ns
// Formula 1: DATAST = tPWE1 / tHCLK = 7 / 6 = 1
// Formula 2: ( (ADDSET + 1) + (DATAST + 1) ) × tHCLK = max (tWC)
// so (ADDSET + 1) = 10 / 6 - ( 1 + 1 ) -> ADDSET = 0
// Verify with Formula 3 below
// DATAST >= (tAA + tsu(Data_NE) + tv(A_NE))/tHCLK – ADDSET – 4
// ADDSET and DATAST should be set to 0 and 1 respectively according to the formula, however, it causes some reading inaccuracy at times.
FSMC_Bank1->BCR1 = (FSMC_BCR1_WREN|FSMC_BCR1_RESERVED|FSMC_BCR1_MWID_0);
ADDSET = 2;
DATAST = 2;
FSMC_Bank1->BTR1 = ADDSET | (DATAST<<
8
);
FSMC_Bank1->BCR1 |= FSMC_BCR1_MBKEN;
// Configure then enable NOR Flash
// tHCLK = 6 ns, tWC = 60 ns, tWP = 25 ns, tAVQV = 100 ns, tsu(Data_NE) = 10 ns, tv(A_NE) = 4.5 ns
// Formula 1: DATAST = tWP / HCLK = 25 / 6 ~= 4
// Formula 2: ( (ADDSET + 1) + (DATAST + 1) ) × tHCLK = max (tWC)
// so (ADDSET + 1) = 60 / 6 - ( 5 + 1 ) -> ADDSET = 4
// Mode 2
FSMC_Bank1->BCR2 = FSMC_BCR2_WREN|
/*FSMC_BCR2_WAITCFG|*/
FSMC_BCR2_RESERVED|
FSMC_BCR2_FACCEN|
FSMC_BCR2_MWID_0|
FSMC_BCR2_MTYP_1;
ADDSET = 4;
DATAST = 4;
FSMC_Bank1->BTR2 = (ADDSET | (DATAST<<
8
)) ;
FSMC_Bank1->BCR2 |= FSMC_BCR2_MBKEN;
// Configure then enable Ethernet (Mode 1)
FSMC_Bank1->BCR4 = (FSMC_BCR4_WREN|FSMC_BCR4_RESERVED|FSMC_BCR4_MWID_0);
ADDSET = 0;
DATAST = 8; //48 ns, Ethernet max access time: 45 ns
FSMC_Bank1->BTR4 = ADDSET | (DATAST<<
8
);
FSMC_Bank1->BCR4 |= FSMC_BCR4_MBKEN;
}
#stm32-fsmc-nor-flash