cancel
Showing results for 
Search instead for 
Did you mean: 

Ethernet not working with external SDRAM in STM32H745 discovery board?

Akast.2
Associate II

Ethernet not working with external SDRAM?

1. I am working on STM32H745i-DISCO board. I am using LWIP stack and internal flash and internal SRAM in MCU.

I configured the ethernet by following the below steps in stm32cube:

a. Ethernet Configuration

-Ethernet mode - MII

- Parameter settings

First Tx descriptor address - 0x30000080

First Rx descriptor address - 0x30000000

Rx Buffers address - 0x30000100

b. LWIP Configuration

  • Enabled the cache (DCache and ICache).
  • MEM_SIZE (Heap Memory Size) - 10*1024 bytes
  • LWIP_RAM_HEAP_POINTER (RAM Heap Pointer) - 0x30002000

c. MPU Configuration

 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 
 MPU_InitStruct.BaseAddress = 0x30000000;
 
 MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
 
 MPU_InitStruct.SubRegionDisable = 0x0;
 
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
 
 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
 
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

d. Modified the flash linker script: I added the following lines in STM32H745XIHX_FLASH.ld file to allocate the space in D2 SRAM which ethernet can access.

 .lwip_sec (NOLOAD) :
 {
  . = ABSOLUTE(0x30000000);
  *(.RxDecripSection)
 
  . = ABSOLUTE(0x30000080);
  *(.TxDecripSection)
 
  . = ABSOLUTE(0x30000100);
  *(.RxArraySection)   
 } >RAM_D2

I verified the same using Build Analyzer tab in STM32CubeIDE in which memory was allocated to lwip section in the required regions.

d. Code:

int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
 
/* USER CODE END Boot_Mode_Sequence_0 */
 
  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();
 
  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();
 
  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();
 
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
  /* Wait until CPU2 boots and enters in stop mode or timeout*/
  timeout = 0xFFFF;
  while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
  if ( timeout < 0 )
  {
  Error_Handler();
  }
/* USER CODE END Boot_Mode_Sequence_1 */
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_2 */
/* When system initialization is finished, Cortex-M7 will release Cortex-M4 by means of
HSEM notification */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/*Take HSEM */
HAL_HSEM_FastTake(HSEM_ID_0);
/*Release HSEM in order to notify the CPU2(CM4)*/
HAL_HSEM_Release(HSEM_ID_0,0);
/* wait until CPU2 wakes up from stop mode */
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
/* USER CODE END Boot_Mode_Sequence_2 */
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LWIP_Init();
  HAL_Delay(2000);
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
         ethernetif_input(&gnetif);
         sys_check_timeouts();
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 4;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOI_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
}
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
/* MPU Configuration */
 
void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};
 
  /* Disables the MPU */
  HAL_MPU_Disable();
  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x30000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
}

With the above steps DHCP and ping was working properly.

Now I want to store my code in external QSPI flash and run the code in external SDRAM.

I followed the same steps for ethernet along with the steps for QSPI and SDRAM but 

ethernet DHCP and ping are not working with external SDRAM. 

Further in the Build analyzer also the space is not allocated for lwip section in D2 SRAM.

My MPU configuration in the later code is 

void MPU_Config(void)
 
{
 
 MPU_Region_InitTypeDef MPU_InitStruct = {0};
 
 
 
 /* Disables the MPU */
 
 HAL_MPU_Disable();
 
 /** Initializes and configures the Region and the memory to be protected
 
 */
 
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 
 MPU_InitStruct.BaseAddress = 0x30000000;
 
 MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
 
 MPU_InitStruct.SubRegionDisable = 0x0;
 
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
 
 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
 
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
 
 
 HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 /** Initializes and configures the Region and the memory to be protected
 
 */
 
 MPU_InitStruct.Number = MPU_REGION_NUMBER1;
 
 MPU_InitStruct.BaseAddress = 0x70000000;
 
 MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
 
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
 
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 
 MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
 
 MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 
 
 
 HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 /** Initializes and configures the Region and the memory to be protected
 
 */
 
 MPU_InitStruct.Number = MPU_REGION_NUMBER2;
 
 MPU_InitStruct.BaseAddress = 0x90000000;
 
 MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
 
 
 
 HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 /* Enables the MPU */
 
 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
 
 
}

2 REPLIES 2
Akast.2
Associate II

Dear ST Team,

I am blocked because of the issue, kindly help by providing a solution to the problem.

Waiting for the reply.

OWLchan
Associate III

Hello, I have the same problem as you, can you let me know if you solved the problem?