2023-05-29 01:54 PM - edited 2023-11-20 04:24 AM
I have a nucleo-stm32f756zg board. I can't make lwIP stack working, which I tested with ping. I have read the relevant documentation (e.g. rm0385, um1974). I have read the official stm32 tutorial for stm32H7 (https://community.st.com/s/article/How-to-create-project-for-STM32H7-with-Ethernet-and-LwIP-stack-working) and adapted to my nucleo board.
I have checked all the Jumpers and soldier bridges are correct. This is a new board by the way, so there was no need to change the default configuration.
I don't know if the following are significant but I mention any oddities during making the project.
(1) This is CubeMX and the MB1137 board documentation side by side and the PA7 doesn't agree. If I try to change it to the correct value, then ETH module gets automatically disabled.
(2) When I configure ETH there is warning message: "The ETH can work only when RAM is pointing at 0x2400 0000." I don't understand this warning, that address is in reserved area:
Maybe the warning message means the DMA descriptors should be after 0x2004c000. In that case the default config is good. On the other hand, according to the rm0385, ethernet DMA has access to all memory, so this shouldn't be an issue even if I got it wrong.
(3) Under Platform Settings I should choose between DP83848 and LAN8742. I couldn't find this in the docs or written on the nucleo board which PHY I have. I tried both settings though, but it didn't work.
If I understand correctly, I don't need to add code, the threads will start and they should respond to ping 192.168.1.10. I did add some code though to the .ld script to make the DMA descriptors positioned to the right address as in the cubeMX configuration.
I uploaded the source here: https://github.com/FitDavid/stm32_lwip_sample
2023-06-13 04:02 AM
Hi,
It is strongly recommended to check the application available in STM32CubeF7 package:
"Projects\STM32F746ZG-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS"
Note: You can run the LwIP_HTTP_Server_Netconn_RTOS application on your nucleo-stm32f756zg.
(1) HAL_ETH_MspInit() should be updated with the correct config (UM1974: User manual: Table 11 Ethernet pins :(
You can update ETH GPIO Settings in MX, click on the right GPIO and choose the correct setting;
Relocate ETH_TX_EN signal from PB11 to PG11.
Note: You should set the new pin (PG11 in our case) to its correct config rather than disabling the wrong one, that way the ETH module doesn't get disabled.
Note: It is better to create the project from board selector, for the pins to be correctly placed, and still you need to confirm the generated config with the board documentation.
Here's the updated config.
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Ethernet pins configuration ************************************************/
/*
RMII_REF_CLK ----------------------> PA1
RMII_MDIO -------------------------> PA2
RMII_MDC --------------------------> PC1
RMII_MII_CRS_DV -------------------> PA7
RMII_MII_RXD0 ---------------------> PC4
RMII_MII_RXD1 ---------------------> PC5
RMII_MII_TX_EN --------------------> PG11
RMII_MII_TXD0 ---------------------> PG13
RMII_MII_TXD1 ---------------------> PB13
*/
/* Configure PA1, PA2 and PA7 */
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure PB13 */
GPIO_InitStructure.Pin = GPIO_PIN_13;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure PC1, PC4 and PC5 */
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PG2, PG11, PG13 and PG14 */
GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
/* Enable the Ethernet global Interrupt */
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn);
/* Enable ETHERNET clock */
__HAL_RCC_ETH_CLK_ENABLE();
}
(2) For the DMA descriptors, the default config is good Ethernet Rx and Tx DMA Descriptors are pointing to the right locations.
(3) For the nucleo-stm32f756zg board, LAN8742 PHY chip is used ( you can find this info in datasheet or in the BOM)
(4) MPU_Config() is added to the software.
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU as Strongly ordered for not defined regions */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU as Normal Non Cacheable for Ethernet Buffers in the SRAM2 */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x20048000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU as Device for Ethernet Descriptors in the SRAM2 */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x2004C000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
The D-Cache is also enabled, so the main() function should look like the following:
int main(void)
{
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache */
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
while (1) {}}
(5) CubeIDE optimization is changed to optimize for debug.
The app is now responding to ping 192.168.1.10.