cancel
Showing results for 
Search instead for 
Did you mean: 

How to store a uint32 to SD-RAM stm32746g discovery with the BSP-Drivers

MMett
Associate III

Hello, I'm using the STM32746G Discovery Board to familiarize myself with the ST environment. Now I simply wanted to store a 32Bit value in the RAM, and had several problems with the Cube BSP drivers. I tested the functions with the following code:

#define SDRAM_OFFSET ((uint32_t)0xC0100000)
 
for(uint32_t i=0; i<0x10010; i++){
	BSP_SDRAM_WriteData(SDRAM_OFFSET+i*4,(uint32_t *)&i,1);
}
for(uint32_t i=0; i<0x10010; i++){
	testarray[i]= 0;
}
for(uint32_t i=0; i<0x10010; i++){
if(SDRAM_OK != BSP_SDRAM_ReadData(SDRAM_OFFSET+i*4,(uint32_t *)(&testarray[i]),1)){
	testarray[i] = 111111;
	}
}

In the debugger it then looks like this:

0690X000006C0XCQA0.png

Sometimes the transfer works. Sometimes the higher bits are incorrect.

How do I use the function to make it work?

Further I could not find out which SD-RAM area is used by the LCD driver. Which area can I overwrite without worrying about disturbing the display functions? Unfortunately I could not read this out of the code.

1 ACCEPTED SOLUTION

Accepted Solutions
MMett
Associate III

As in many examples I found online the clocks are configured with a function void SystemClock_Config(void). To make the display work, I copied the function from an example. It caused the error in the SD-Ram write process. As I read from the comments, the SD-RAM can be operated up to a system clock of 200MHz. If I understood it correctly, mine has been set to 216MHz. Now I have the following clock configuration function:

void SystemClock_Config(void)
{
	/**Macro to configure the PLL multiplication factor*/
	__HAL_RCC_PLL_PLLM_CONFIG(16);
 
	/**Macro to configure the PLL clock source*/
	__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);
 
	/**Configure the main internal regulator output voltage*/
	__HAL_RCC_PWR_CLK_ENABLE();
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
	RCC_OscInitTypeDef RCC_OscInitStruct;
	//RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
	HAL_StatusTypeDef ret = HAL_OK;
 
	/* Enable HSE Oscillator and activate PLL with HSE as source */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLM = 25;
	RCC_OscInitStruct.PLL.PLLN =380;// old value: 400
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 8;
 
	ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
	if(ret != HAL_OK){
		_Error_Handler(__FILE__, __LINE__);
	}
 
	/* Activate the OverDrive to reach the 200 MHz Frequency */
	ret = HAL_PWREx_EnableOverDrive();
	if(ret != HAL_OK){
		_Error_Handler(__FILE__, __LINE__);
	}
 
	/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
	RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
	ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
	if(ret != HAL_OK){
		_Error_Handler(__FILE__, __LINE__);
	}
 
	/**Configure the Systick interrupt time*/
	HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
	/**Configure the Systick*/
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
	/* SysTick_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

To make the diplay and RAM work, I changed the RCC_OscInitStruct.PLL.PLLN from 400 to 380. I guess more or less: PLLN = 400: 216MHz, so PLLN=380: 200MHz.

Find it difficult to read from the TRM which PLL is now responsible for what. If someone has a better solution, I would be interested in it. This has now solved the problem for me temporarily.

View solution in original post

15 REPLIES 15
MMett
Associate III

I am still struggling with this problem. Does nobody have any suggestions or tips for me?

testarray is in Internal SRAM

0x10010 is significantly larger than 10000 decimal (0..9999)

SDRAM writes like other memory, you could just use a pointer.

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

Thanks for the reaction. I'm not sure I understood you correctly. If I do it that way, I get exactly the same result (with 16 entries):

BSP_SDRAM_Init();
 
#define TESTSIZE 16
uint32_t testarray[TESTSIZE];
for(uint32_t i=0; i<TESTSIZE; i++){
	testarray[i]= i;
}
BSP_SDRAM_WriteData(MIC_SDRAM_OFFSET,testarray,TESTSIZE);
for(uint32_t i=0; i<TESTSIZE; i++){
	testarray[i]= 0;
}
BSP_SDRAM_ReadData(MIC_SDRAM_OFFSET,testarray,TESTSIZE);

Ok, that with the pointer I think I understood. But I still have the same result:

uint32_t * sdramarray;
sdramarray = MIC_SDRAM_OFFSET;
 
uint32_t testarray[TESTSIZE];
for(uint32_t i=0; i<TESTSIZE; i++){
	testarray[i]= i;
}
for(uint32_t i=0; i<TESTSIZE; i++){
	sdramarray[i] = testarray[i];
}
for(uint32_t i=0; i<TESTSIZE; i++){
	testarray[i]= 0;
}
for(uint32_t i=0; i<TESTSIZE; i++){
	testarray[i]= sdramarray[i];
}

MMett
Associate III

After trying for hours, it looks like I've found a solution. I found in the file: stm32746g_discovery_sdram.h the macro: SDRAM_MEMORY_WIDTH

I changed it from FMC_SDRAM_MEM_BUS_WIDTH_16 to FMC_SDRAM_MEM_BUS_WIDTH_8.

I have no idea what I did, but in any case the read-write check works now. Let's see what else awaits me. If someone can explain to me what I have changed there exactly, I am curious.

Without modification of BSP files

#define TESTSIZE 256
uint32_t testarray[TESTSIZE];
#define SDRAM_OFFSET ((uint32_t)0xC0100000)
 
...
 
	BSP_SDRAM_Init();
 
  /* Add your application code here
     */
 
	for(uint32_t i=0; i<TESTSIZE; i++){
		testarray[i]= i;
	}
	
	BSP_SDRAM_WriteData(SDRAM_OFFSET, testarray, TESTSIZE);
 
	for(uint32_t i=0; i<TESTSIZE; i++){
		testarray[i]= 0;
	}
 
	BSP_SDRAM_ReadData(SDRAM_OFFSET, testarray, TESTSIZE);
 
	printf("From 0x%08X\n", SDRAM_OFFSET);
	for(uint32_t i=0; i<TESTSIZE; i++){
		if (i && ((i % 8) == 0))
			putchar('\n');
		printf(" %08X", testarray[i]);
	}
	putchar('\n');
	
	{
		uint32_t *sdram = (uint32_t *)0xC0000000;
		uint32_t i, j = (8 * 1024 * 1024) / 4; // 64Mbit 8MB accesed as words
		
		for(i=0; i<j; i++) sdram[i] = i;
		
		for(i=0; i<j; i++)
		{
			if (sdram[i] != i)
			{
				printf("SDRAM Failed at 0x%08X\n", i);
			}
		}
		
		if (i == j) puts("SDRAM Passed");
	}
...
STM32F746G-DISCO
 
Core=216000000, 216 MHz
CPUID 410FC271 DEVID 449 REVID 1001
Cortex M7 r0p1
STM32F74xxx or F75xxx
C0000000 FFFFFFF8 00000000
10110021 11000011 00000040
FPU-S Single-precision only
APB1=54000000
APB2=108000000
From 0xC0100000
 00000000 00000001 00000002 00000003 00000004 00000005 00000006 00000007
 00000008 00000009 0000000A 0000000B 0000000C 0000000D 0000000E 0000000F
 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017
 00000018 00000019 0000001A 0000001B 0000001C 0000001D 0000001E 0000001F
 00000020 00000021 00000022 00000023 00000024 00000025 00000026 00000027
 00000028 00000029 0000002A 0000002B 0000002C 0000002D 0000002E 0000002F
 00000030 00000031 00000032 00000033 00000034 00000035 00000036 00000037
 00000038 00000039 0000003A 0000003B 0000003C 0000003D 0000003E 0000003F
 00000040 00000041 00000042 00000043 00000044 00000045 00000046 00000047
 00000048 00000049 0000004A 0000004B 0000004C 0000004D 0000004E 0000004F
 00000050 00000051 00000052 00000053 00000054 00000055 00000056 00000057
 00000058 00000059 0000005A 0000005B 0000005C 0000005D 0000005E 0000005F
 00000060 00000061 00000062 00000063 00000064 00000065 00000066 00000067
 00000068 00000069 0000006A 0000006B 0000006C 0000006D 0000006E 0000006F
 00000070 00000071 00000072 00000073 00000074 00000075 00000076 00000077
 00000078 00000079 0000007A 0000007B 0000007C 0000007D 0000007E 0000007F
 00000080 00000081 00000082 00000083 00000084 00000085 00000086 00000087
 00000088 00000089 0000008A 0000008B 0000008C 0000008D 0000008E 0000008F
 00000090 00000091 00000092 00000093 00000094 00000095 00000096 00000097
 00000098 00000099 0000009A 0000009B 0000009C 0000009D 0000009E 0000009F
 000000A0 000000A1 000000A2 000000A3 000000A4 000000A5 000000A6 000000A7
 000000A8 000000A9 000000AA 000000AB 000000AC 000000AD 000000AE 000000AF
 000000B0 000000B1 000000B2 000000B3 000000B4 000000B5 000000B6 000000B7
 000000B8 000000B9 000000BA 000000BB 000000BC 000000BD 000000BE 000000BF
 000000C0 000000C1 000000C2 000000C3 000000C4 000000C5 000000C6 000000C7
 000000C8 000000C9 000000CA 000000CB 000000CC 000000CD 000000CE 000000CF
 000000D0 000000D1 000000D2 000000D3 000000D4 000000D5 000000D6 000000D7
 000000D8 000000D9 000000DA 000000DB 000000DC 000000DD 000000DE 000000DF
 000000E0 000000E1 000000E2 000000E3 000000E4 000000E5 000000E6 000000E7
 000000E8 000000E9 000000EA 000000EB 000000EC 000000ED 000000EE 000000EF
 000000F0 000000F1 000000F2 000000F3 000000F4 000000F5 000000F6 000000F7
 000000F8 000000F9 000000FA 000000FB 000000FC 000000FD 000000FE 000000FF
SDRAM Passed 

 Output via ST-LINK VCP at 115200 8N1

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

Thank you for you check! Your code does not work in my case. I updated also the BSP Drivers from STM32Cube FW V1.12.0 to V1.14.0 without improvement.

Could it be due to a different compiler? I use GNU MCU Eclipse ARM Embedded GCC (arm-none-eabi-gcc). Or the clock configuration? That's the only thing I call up before the test, and in my understanding could influence the SD-RAM.

Or the RAM is damaged, which I can hardly imagine.

I supplied a working HEX file to avoid any dependencies on what else you were doing.​

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

I just could program your hex-file. It gives me the same result as you posted above. So the SD-RAM is working fine.