2020-11-16 12:07 AM
Hello everyone,
I've an STM32F7 Discovery Board. I've been playing with all of the peripherals such a USART, I2C, GPIO, LTDC and SDRAM. And, I've been problems with this last one.
I want to do enphasis in that I use to program the device with Atollic and filling the register, instead of use HAL Libraries.
I've been trying only writting a few bits, but the result is the same. For example, if I write 0xABCD, the SDRAM lecture is 0xA9CD, so probably is not aligment correctly.
The Reference Manual said, that the SDRAM should be located in Bank 5 or Bank 6, which means 0xC000 0000 to 0xCFFF FFFF, or 0xD000 0000 to 0xDFFF FFFF.
#define SDRAM_ADDR (uint32_t)0xC0000000 //SDRAM Bank 1
#define DEVICE_SIZE (uint32_t)0x800000 //SDRAM Size 8MB
uint32_t *sdram = (uint32_t*)0xC0000000;
volatile uint16_t buffer_tft;
void SRAM_Config(void){
//----------- GPIO -------------//
//PE1 FMC_NBL1
GPIOE->MODER |= (2<<2); //Alternate function
GPIOE->OSPEEDR |= (3<<2); //Very High speed
GPIOE->AFR[0] |= (12<<4); //AF12 Pin 1
//PE0 FMC_NBL0
GPIOE->MODER |= (2<<0); //Alternate function
GPIOE->OSPEEDR |= (3<<0); //Very High speed
GPIOE->AFR[0] |= (12<<0); //AF12 Pin 0
//PG15 FMC_SDNCAS
GPIOG->MODER |= (2<<30); //Alternate function
GPIOG->OSPEEDR |= (3<<30); //Very High speed
GPIOG->AFR[1] |= (12<<28); //AF12 Pin 15
//PD0 FMC_D2_DA2
GPIOD->MODER |= (2<<0); //Alternate function
GPIOD->OSPEEDR |= (3<<0); //Very High speed
GPIOD->AFR[0] |= (12<<0); //AF12 Pin 0
//PD1 FMC_D3_DA3
GPIOD->MODER |= (2<<2); //Alternate function
GPIOD->OSPEEDR |= (3<<2); //Very High speed
GPIOD->AFR[0] |= (12<<4); //AF12 Pin 1
//PF0 FMC_A0
GPIOF->MODER |= (2<<0); //Alternate function
GPIOF->OSPEEDR |= (3<<0); //Very High speed
GPIOF->AFR[0] |= (12<<0); //AF12 Pin 0
//PF1 FMC_A1
GPIOF->MODER |= (2<<2); //Alternate function
GPIOF->OSPEEDR |= (3<<2); //Very High speed
GPIOF->AFR[0] |= (12<<4); //AF12 Pin 1
//PF2 FMC_A2
GPIOF->MODER |= (2<<4); //Alternate function
GPIOF->OSPEEDR |= (3<<4); //Very High speed
GPIOF->AFR[0] |= (12<<8); //AF12 Pin 2
//PF3 FMC_A3
GPIOF->MODER |= (2<<6); //Alternate function
GPIOF->OSPEEDR |= (3<<6); //Very High speed
GPIOF->AFR[0] |= (12<<12); //AF12 Pin 2
//PG8 FMC_SDCLK
GPIOG->MODER |= (2<<16); //Alternate function
GPIOG->OSPEEDR |= (3<<16); //Very High speed
GPIOG->AFR[1] |= (12<<0); //AF12 Pin 8
//PF4 FMC_A4
GPIOF->MODER |= (2<<8); //Alternate function
GPIOF->OSPEEDR |= (3<<8); //Very High speed
GPIOF->AFR[0] |= (12<<16); //AF12 Pin 4
//PH5 FMC_SDNWE
GPIOH->MODER |= (2<<10); //Alternate function
GPIOH->OSPEEDR |= (3<<10); //Very High speed
GPIOH->AFR[0] |= (12<<20); //AF12 Pin 5
//PH3 FMC_SDNE0
GPIOH->MODER |= (2<<6); //Alternate function
GPIOH->OSPEEDR |= (3<<6); //Very High speed
GPIOH->AFR[0] |= (12<<12); //AF12 Pin 3
//PF5 FMC_A5
GPIOF->MODER |= (2<<10); //Alternate function
GPIOF->OSPEEDR |= (3<<10); //Very High speed
GPIOF->AFR[0] |= (12<<20); //AF12 Pin 5
//PD15 FMC_D1_DA1
GPIOD->MODER |= (2<<30); //Alternate function
GPIOD->OSPEEDR |= (3<<30); //Very High speed
GPIOD->AFR[1] |= (12<<28); //AF12 Pin 15
//D10 FMC_D15_DA15
GPIOD->MODER |= (2<<20); //Alternate function
GPIOD->OSPEEDR |= (3<<20); //Very High speed
GPIOD->AFR[1] |= (12<<8); //AF10 Pin 10
//PC3 FMC_SDCKE0
GPIOC->MODER |= (2<<6); //Alternate function
GPIOC->OSPEEDR |= (3<<6); //Very High speed
GPIOC->AFR[0] |= (12<<12); //AF12 Pin 3
//PD14 FMC_D0_DA0
GPIOD->MODER |= (2<<28); //Alternate function
GPIOD->OSPEEDR |= (3<<28); //Very High speed
GPIOD->AFR[1] |= (12<<24); //AF12 Pin 14
//PD9 FMC_D14_DA14
GPIOD->MODER |= (2<<18); //Alternate function
GPIOD->OSPEEDR |= (3<<18); //Very High speed
GPIOD->AFR[1] |= (12<<4); //AF12 Pin 9
//PD8 FMC_D13_DA13
GPIOD->MODER |= (2<<16); //Alternate function
GPIOD->OSPEEDR |= (3<<16); //Very High speed
GPIOD->AFR[1] |= (12<<0); //AF12 Pin 8
//PF12 FMC_A6
GPIOF->MODER |= (2<<12); //Alternate function
GPIOF->OSPEEDR |= (3<<12); //Very High speed
GPIOF->AFR[1] |= (12<<16); //AF12 Pin 12
//PG1 FMC_A11
GPIOG->MODER |= (2<<2); //Alternate function
GPIOG->OSPEEDR |= (3<<2); //Very High speed
GPIOG->AFR[0] |= (12<<4); //AF12 Pin 1
//PF15 FMC_A9
GPIOF->MODER |= (2<<30); //Alternate function
GPIOF->OSPEEDR |= (3<<30); //Very High speed
GPIOF->AFR[1] |= (12<<28); //AF12 Pin 15
//PF13 FMC_A7
GPIOF->MODER |= (2<<26); //Alternate function
GPIOF->OSPEEDR |= (3<<26); //Very High speed
GPIOF->AFR[1] |= (12<<20); //AF12 Pin 13
//PG0 FMC_A10
GPIOG->MODER |= (2<<0); //Alternate function
GPIOG->OSPEEDR |= (3<<0); //Very High speed
GPIOG->AFR[0] |= (12<<0); //AF12 Pin 0
//PE8 FMC_D5_DA5
GPIOE->MODER |= (2<<16); //Alternate function
GPIOE->OSPEEDR |= (3<<16); //Very High speed
GPIOE->AFR[1] |= (12<<0); //AF12 Pin 8
//PG5 FMC_D14_DA14
GPIOG->MODER |= (2<<10); //Alternate function
GPIOG->OSPEEDR |= (3<<10); //Very High speed
GPIOG->AFR[0] |= (12<<20); //AF12 Pin 5
//PG4 FMC_A14_BA0
GPIOG->MODER |= (2<<8); //Alternate function
GPIOG->OSPEEDR |= (3<<8); //Very High speed
GPIOG->AFR[0] |= (12<<16); //AF12 Pin 4
//PF14 FMC_A8
GPIOF->MODER |= (2<<28); //Alternate function
GPIOF->OSPEEDR |= (3<<28); //Very High speed
GPIOF->AFR[1] |= (12<<24); //AF12 Pin 14
//PF11 FMC_SDNRAS
GPIOF->MODER |= (2<<22); //Alternate function
GPIOF->OSPEEDR |= (3<<22); //Very High speed
GPIOF->AFR[1] |= (12<<12); //AF12 Pin 11
//PE9 FMC_D6_DA6
GPIOE->MODER |= (2<<18); //Alternate function
GPIOE->OSPEEDR |= (3<<18); //Very High speed
GPIOE->AFR[1] |= (12<<4); //AF12 Pin 9
//PE11 FMC_D8_DA8
GPIOE->MODER |= (2<<22); //Alternate function
GPIOE->OSPEEDR |= (3<<22); //Very High speed
GPIOE->AFR[1] |= (12<<12); //AF12 Pin 11
//PE14 FMC_D11_DA11
GPIOE->MODER |= (2<<28); //Alternate function
GPIOE->OSPEEDR |= (3<<28); //Very High speed
GPIOE->AFR[1] |= (12<<24); //AF12 Pin 14
//PE7 FMC_D4_DA4
GPIOE->MODER |= (2<<14); //Alternate function
GPIOE->OSPEEDR |= (3<<14); //Very High speed
GPIOE->AFR[0] |= (12<<28); //AF12 Pin 7
//PE10 FMC_D7_DA7
GPIOE->MODER |= (2<<20); //Alternate function
GPIOE->OSPEEDR |= (3<<20); //Very High speed
GPIOE->AFR[1] |= (12<<8); //AF12 Pin 10
//---------------------------------------------//
#define TMRD(x) (x << 0) /* Load Mode Register to Active */
#define TXSR(x) (x << 4) /* Exit Self-refresh delay */
#define TRAS(x) (x << 8) /* Self refresh time */
#define TRC(x) (x << 12) /* Row cycle delay */
#define TWR(x) (x << 16) /* Recovery delay */
#define TRP(x) (x << 20) /* Row precharge delay */
#define TRCD(x) (x << 24) /* Row to column delay */
//Although the SDRAM is designed for Bank 5, we've to configure the both
/*FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_0 | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE_1; //SDCLK = HCLK/2 | Single read Managed as burst | Pipe Read two cycle clock delay
FMC_Bank5_6->SDCR[0] = FMC_SDCR1_NR_0 | FMC_SDCR1_MWID_0 | FMC_SDCR1_NB | FMC_SDCR1_CAS; //12 bits Row Address | 16 Bits data bus width | Four Internal Banks | Cas Latency 3 Cycles
FMC_Bank5_6->SDTR[0] = TRC(7) | TRP(2);
FMC_Bank5_6->SDTR[0] = TMRD(2) | TXSR(7) | TRAS(4) | TWR(3) | TRCD(2);*/
FMC_Bank5_6->SDCR[0]= 0x19D4;
FMC_Bank5_6->SDTR[0] = 0x1126361;
delay_ms(100);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank5_6->SDCMR |= (1<<FMC_SDCMR_MODE_Pos) | FMC_SDCMR_CTB1 | (1 << FMC_SDCMR_NRFS_Pos); //Mode: CLock configuration | Bank 1 | 2 Auto refrech Cycles Modes
delay_ms(100);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank5_6->SDCMR = (2<<FMC_SDCMR_MODE_Pos) | FMC_SDCMR_CTB1 | (1 << FMC_SDCMR_NRFS_Pos);//Mode: PALL
delay_ms(1);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank5_6->SDCMR = (3<<FMC_SDCMR_MODE_Pos) | FMC_SDCMR_CTB1 | (4 << FMC_SDCMR_NRFS_Pos);//Mode: Auto refresh Command | 5 Auto refresh cucles
delay_ms(1);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank5_6->SDCMR = (4<<FMC_SDCMR_MODE_Pos) | FMC_SDCMR_CTB1 | (1 << FMC_SDCMR_NRFS_Pos) | (0x220 << 9); //Mode: Load Mode register | 2 Auto refresh Cycles | Mode registration definition 0x231
delay_ms(1);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank5_6->SDRTR |= (0x0603 << 1); //Refresh Timer Register Value
delay_ms(1);
while(FMC_Bank5_6->SDSR & FMC_SDSR_BUSY);
FMC_Bank1->BTCR[0] = 0x000030d2;
int tmp =0;
UART_Send_String("Clearing SDRAM...\n");
for(tmp = 0; tmp<DEVICE_SIZE; tmp+=4){
*(uint16_t *) (SDRAM_ADDR + tmp) = (uint32_t)0x00000000;
}
UART_Send_String("SDRAM Cleared\n");
UART_Send_String("READING SDRAM...\n");
DMA_4_SDRAM();
}
Best regards,
Jorge.
2020-11-16 05:29 AM
If the memory is otherwise working except that one bit is incorrect (0xABCD vs 0xA9CD), check the signal path for that bit to ensure the hardware connection is correct, and ensure pin settings for that bit are correct. If your signal path is significantly longer on that signal than the others, this can also cause problems.
Edit: not a custom board. F7-disco board.
2020-11-16 05:51 AM
Hi TDK,
Many thanks for your reply.
I'm using the STM32f746G Discovery board, so I suppose that the length macthing is correct. Perhaps, I could missconnect the pins. Probably the address pins or the data pins, and then, I've that kind of missmatch.
Also I've been reading about ARM v7 cores has redirection troubles from 0xC000 0000 to 0xC03F FFFF when you connect an external SDRAM, and the bits are not alignment, so maybe could be possible that exists another possibility. I leave you here the link and we can discuss about it if you want. I'm trying to do the same that the topic recommends but I've problems with the MPU directives, because I'm not using HAL libs.
https://www.keil.com/support/docs/3777.htm
Best regards,
Jorge.
2020-11-16 07:55 AM
Hi Jorge,
I'm using 20+ such board in my student labs for 2 years and there are basically no memory issues with it, especially never heard of "redirection troubles".
Think there might be a typo in your code. I would recommend comparing to the board support package code which comes with the F7 firmware download or online https://github.com/STMicroelectronics/STM32CubeF7/tree/master/Drivers/BSP/STM32746G-Discovery
2020-11-16 12:29 PM
Hi KnarfB,
I was comparing the pinout from the 32F746NG-DISCO with the link that you shared with me. And, you was complety right. I've been using the datasheet as reference for the board pinout, and in it, it doesn't appear the PE15, PE13 and PE12, which means that my code doesn't have DA[12], DA[10] and DA[9] bits, so then, the result after write and read it wasn't correct.
Here, I leave you the datasheet:
You can try to find thats pins, and try to find if they exist inside it.
Also, I attach you the link from ARM where they talk about the trouble in the memory aligment that I commented.
Now, I've to try if a full image, it's correctly copied from RAM to LCD buffer with the DMA in the conflictic memory regions.
https://www.keil.com/support/docs/3777.htm
I'll advise you about my progress, but at least today, I've been able to get SDRAM works.
Many thanks,
Jorge.
2020-11-16 12:45 PM
Hi Jorge,
glad you found the reason. You're right, the data sheet is missing those pins, too bad.
KnarfB
2020-11-18 05:50 AM
Hello @Jde C.1 ,
Thank you for your reported issue.
I rasied internally your feedback to add missing pins on the UM1907.
Imen