cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 and Extern SDRAM Bank Accessing Problem

michaelmichael9137
Associate II

Hi everyone,

I'm using a STM32F769BGT6 with an external SDRAM (IS42S32400F). This SDRAM is composed of 4 banks. Each bank contains 12 Rows (4096), 8 Columns (256), and each cell is 32 bits. So : 4096*256*32 = 33 554 432 bits, or 4MBytes/Bank. That means that it can store 4x1M uint32 variables.

I've done the configuration in system_stm32f7xx.c, because i need to use it as a memory section. Here is the initialization code :

void SystemInit_ExtMemCtl(void)
{
  __IO uint32_t tmp = 0;
 
  register uint32_t tmpreg = 0, timeout = 0xFFFF;
  register uint32_t index;
 
  /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
  RCC->AHB1ENR |= 0x000001F8;
  
  /* Delay after an RCC peripheral clock enabling */
  tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);
  
  /* Connect PDx pins to FMC Alternate function */
  GPIOD->AFR[0]  = 0x000000CC;
  GPIOD->AFR[1]  = 0xCC000CCC;
  /* Configure PDx pins in Alternate function mode */  
  GPIOD->MODER   = 0xA02A000A;
  /* Configure PDx pins speed to 100 MHz */  
  GPIOD->OSPEEDR = 0xF03F000F;
  /* Configure PDx pins Output type to push-pull */  
  GPIOD->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PDx pins */ 
  GPIOD->PUPDR   = 0x50150005;
 
  /* Connect PEx pins to FMC 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   = 0x55554005;
 
  /* Connect PFx pins to FMC Alternate function */
  GPIOF->AFR[0]  = 0x00CCCCCC;
  GPIOF->AFR[1]  = 0xCCCCC000;
  /* Configure PFx pins in Alternate function mode */   
  GPIOF->MODER   = 0xAA800AAA;
  /* Configure PFx pins speed to 100 MHz */ 
  GPIOF->OSPEEDR = 0xFFC00FFF;
  /* Configure PFx pins Output type to push-pull */  
  GPIOF->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PFx pins */ 
  GPIOF->PUPDR   = 0x55400555;
 
  /* Connect PGx pins to FMC Alternate function */
  GPIOG->AFR[0]  = 0x00CC00CC;
  GPIOG->AFR[1]  = 0xC000000C;
  /* Configure PGx pins in Alternate function mode */ 
  GPIOG->MODER   = 0x80020A0A;
  /* Configure PGx pins speed to 100 MHz */ 
  GPIOG->OSPEEDR = 0xC0030F0F;
  /* Configure PGx pins Output type to push-pull */  
  GPIOG->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PGx pins */ 
  GPIOG->PUPDR   = 0x40010505;
  
  /* Connect PHx pins to FMC Alternate function */
  GPIOH->AFR[0]  = 0x00C0CC00;
  GPIOH->AFR[1]  = 0xCCCCCCCC;
  /* Configure PHx pins in Alternate function mode */ 
  GPIOH->MODER   = 0xAAAA08A0;
  /* Configure PHx pins speed to 100 MHz */ 
  GPIOH->OSPEEDR = 0xFFFF0CF0;
  /* Configure PHx pins Output type to push-pull */  
  GPIOH->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PHx pins */ 
  GPIOH->PUPDR   = 0x55550450;
  
  /* Connect PIx pins to FMC Alternate function */
  GPIOI->AFR[0]  = 0xCCCCCCCC;
  GPIOI->AFR[1]  = 0x00000CC0;
  /* Configure PIx pins in Alternate function mode */ 
  GPIOI->MODER   = 0x0028AAAA;
  /* Configure PIx pins speed to 100 MHz */ 
  GPIOI->OSPEEDR = 0x003CFFFF;
  /* Configure PIx pins Output type to push-pull */  
  GPIOI->OTYPER  = 0x00000000;
  /* No pull-up, pull-down for PIx pins */ 
  GPIOI->PUPDR   = 0x00145555;
  
/*-- FMC Configuration ------------------------------------------------------*/
  /* Enable the FMC interface clock */
  RCC->AHB3ENR |= 0x00000001;
  // FMC_Bank5_6->MWID = 0x
  /* Delay after an RCC peripheral clock enabling */
  tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
 
  /* Configure and enable SDRAM bank1 */
  FMC_Bank5_6->SDCR[0] = 0x00001BE4;
  FMC_Bank5_6->SDTR[0] = 0x01115361;
 
  /* SDRAM initialization sequence */
  /* Clock enable command */
  FMC_Bank5_6->SDCMR = 0x00000011; 
  tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
  while((tmpreg != 0) && (timeout-- > 0))
  {
    tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
  }
 
  /* Delay */
  for (index = 0; index<1000; index++);
  
  /* PALL command */
  FMC_Bank5_6->SDCMR = 0x00000012;           
  timeout = 0xFFFF;
  while((tmpreg != 0) && (timeout-- > 0))
  {
    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
  }
  
  /* Auto refresh command */
  FMC_Bank5_6->SDCMR = 0x000000F3;
  timeout = 0xFFFF;
  while((tmpreg != 0) && (timeout-- > 0))
  {
    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
  }
 
  /* MRD register program */
  FMC_Bank5_6->SDCMR = 0x00046014;
  timeout = 0xFFFF;
  while((tmpreg != 0) && (timeout-- > 0))
  {
    tmpreg = FMC_Bank5_6->SDSR & 0x00000020; 
  } 
  
  /* Set refresh count */
  tmpreg = FMC_Bank5_6->SDRTR;
  FMC_Bank5_6->SDRTR = (tmpreg | (0x00000603<<1));
  
  /* Disable write protection */
  tmpreg = FMC_Bank5_6->SDCR[0];
  FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
  
  /*
   * Disable the FMC bank1 (enabled after reset).
   * This, prevents CPU speculation access on this bank which blocks the use of FMC during
   * 24us. During this time the others FMC master (such as LTDC) cannot use it!
   */
  FMC_Bank1->BTCR[0] = 0x000030d2;
 
  (void)(tmp);
}

On line 94 of this code snippet, you can see this value for SDCR register :

FMC_Bank5_6->SDCR[0] = 0x00001BE4;

The "B" means that I chose a Memory Data Bus Width of 32 bits.

I made a modification in the linker to add a memory section like follows :

/* Specify the memory areas */
MEMORY
{
RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 512K
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
SDRAM (xrw)     : ORIGIN = 0xC0000000, LENGTH = 16M
}
 
/* Define output sections */
SECTIONS
{
  /* Section créée pour l'allocation dans la SDRAM externe*/
  .masection :
  {
    . = ALIGN(4);
    *(.masection)        
    *(.masection*)
    . = ALIGN(4);
  } >SDRAM

The following code, in the main.c, tests that I can write in the entire memory :

const uint32_t testSize2 = 4000000;
 
uint32_t volatile memoryTest2[testSize2] __attribute__((section(".masection")));
 
  for(size_t i = 0; i < testSize2; i++)
  {
    memoryTest2[i] = i;
  }
 
  for(size_t i = 0; i < testSize2; i++)
  {
    if(memoryTest2[i] != i) __DEBUG_BKPT();
  }

It creates a tab of 4M uint32, and works perfectly.

Sorry for the long intro, but I wanted this to be very clear for you and for myself.

Now my question is :

I need to use a Memory Data Bus Width of 8 bits, instead of 32, because I will use this memory section exclusively with 8 bits words.

For this, I simply changed FMC_Bank5_6->SDCR[0] = 0x00001CE4;

Now, I cannot create a tab of 4M uint32t anymore, I'm limited to 1M. If I try to add more, I have a hardfault. I have the feeling that the low level FMC drivers are not dealing with 8 bits data width properly.

This is very frustrating because 1/4 of my memory is not accessible and I'm stuck.

If anyone has an idea on this, it would be great!

Thanks for your time.

15 REPLIES 15
michaelmichael9137
Associate II

It works perfectly when using words though, so how could it be pin related?

Hi Clive,

Ok I tested the DISCO code, with proper conf for my board, and the behaviour is exactly the same. It's working for 32 bit, but not for 8 bit.

I updated the schematics from my previous post with more hi-res files, sorry about that.

I noticed something when checking the pinout :

0690X0000089zwaQAA.png

The three first columns are what I actually have wired on the PCB. You can see that the third block of eight pins (DQ16 : DQ23) are reversed.

I also noticed that none of the data pins are wired on the GPIO like indicated on the reference manual (last column).

Could it have an impact on the outcome of my read/write attempts?

Because your data bus is all muddled up. The byte positions don't match up with the signals.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Yes, going through it now, the byte positions are muddled up.

Bit reversal within the byte would be tolerable, probably, but the byte lane signals would need to map properly, and the bits here don't map well

As I see it D0..D7 on schematic map to D27, D2, D3, D28, D29, D26, D30, D31 (mix of lane 3 and lane 0)

At a bit level I think this will impact the config words written also

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
BOARD PIN   STM32F769
 
D0  PI3  D27
D1  PD0  D2
D2  PD1  D3
D3  PI6  D28
D4  PI7  D29
D5  PI2  D26
D6  PI9  D30
D7  PI10 D31
 
D8  PD10 D15
D9  PD14 D0
D10 PD15 D1
D11 PH13 D21
D12 PH14 D22
D13 PH15 D23
D14 PI0  D24
D15 PI1  D25
 
D16 PE14 D11
D17 PE13 D10
D18 PE12 D9
D19 PE11 D8
D20 PE10 D7
D21 PE9  D6
D22 PE8  D5
D23 PE7  D4
 
D24 PE15 D12
D25 PH8  D16
D26 PH9  D17
D27 PH10 D18
D28 PH11 D19
D29 PH12 D20
D30 PD8  D13
D31 PD9  D14
 
 
Sorted by STM32 order
 
D9  PD14 D00 LANE 0
D10 PD15 D01
D1  PD0  D02
D2  PD1  D03
D23 PE7  D04
D22 PE8  D05
D21 PE9  D06
D20 PE10 D07
 
D19 PE11 D08 LANE 1
D18 PE12 D09
D17 PE13 D10
D16 PE14 D11
D24 PE15 D12
D30 PD8  D13
D31 PD9  D14
D8  PD10 D15
 
D25 PH8  D16 LANE 2
D26 PH9  D17
D27 PH10 D18
D28 PH11 D19
D29 PH12 D20
D11 PH13 D21
D12 PH14 D22
D13 PH15 D23
 
D14 PI0  D24 LANE 3
D15 PI1  D25
D5  PI2  D26
D0  PI3  D27
D3  PI6  D28
D4  PI7  D29
D6  PI9  D30
D7  PI10 D31

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lix Paulian
Senior

This is an old thread, I suspect that the issue has been solved in a way or the other. However the correct resolution can be found here:

https://www.keil.com/support/docs/3777.htm

I stumbled on this and I spent almost two days debugging this one. It is an issue with the FMC and misaligned accesses in the SDRAM area (addresses above 0xC0000000). I am adding this post here for those who may have the same problem. There is no mention on this in the STM32Fxx manual. I don't want to detail the possible solutions here (follow the link), however suffice to say that I used the MPU recommendation and it worked perfectly for me.