STM32H743以太网驱动调试

硬件环境: 基于STM32H743IIT6自研单板 (1)外部时钟:25MHz (2)调试串口: PC12 ———> UART5_TX PD2 ———> UART5_RX (3)SPI6 PG12 ———> SPI6_MISO PG13 ———> SPI6_SCK PG14 ———> SPI6_MOSI PG8 ———> SPI6_NSS


(相关资料图)

软件开发环境 RT-ThreadStudio 版本: 2.2.6 构建ID: 202211231640 OS: Windows 10, v.10.0, x86_64 / win32

调试串口+以太网

RT-Thread配置

SPI配置 在board.h文件中,参考SPI配置说明依次配置SPI参数

/ -------------------------- SPI CONFIG BEGIN --------------------------/ /** if you want to use spi bus you canuse the following instructions.

STEP 1, open spi driver framework support in the RT-Thread Settings file

STEP 2, define macro related to the spi bus* ``` such as #define BSP_USING_SPI1

STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file

such as     void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)

STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals

such as     #define HAL_SPI_MODULE_ENABLED

/ #define BSP_USING_SPI /#define BSP_USING_SPI1*/ / #define BSP_USING_SPI2/ / #define BSP_USING_SPI3/ / #define BSP_USING_SPI4/ / #define BSP_USING_SPI5/ #define BSP_USING_SPI6 / -------------------------- SPI CONFIG END --------------------------/ 在board.c文件中添加HAL_SPI_MspInit函数

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; if(spiHandle->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspInit 0 / /USER CODE END SPI1_MspInit 0 / /* Initializes the peripherals clock/ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /SPI1 clock enable */ __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**SPI1 GPIO Configuration PG9 ------> SPI1_MISO PG11 ------> SPI1_SCK PB5 ------> SPI1_MOSI/ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /SPI1 interrupt Init / HAL_NVIC_SetPriority(SPI1_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); /USER CODE BEGIN SPI1_MspInit 1 / /USER CODE END SPI1_MspInit 1 */ } else if(spiHandle->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspInit 0 */ /* USER CODE END SPI2_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI2; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI2 clock enable */ __HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOI_CLK_ENABLE(); /**SPI2 GPIO Configuration PB10 ------> SPI2_SCK PB15 ------> SPI2_MOSI PI2 ------> SPI2_MISO */ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); /* SPI2 interrupt Init */ HAL_NVIC_SetPriority(SPI2_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI2_IRQn); /* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */ } else if(spiHandle->Instance==SPI3) { /* USER CODE BEGIN SPI3_MspInit 0 */ /* USER CODE END SPI3_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI3; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI3 clock enable */ __HAL_RCC_SPI3_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /**SPI3 GPIO Configuration PB2 ------> SPI3_MOSI PC10 ------> SPI3_SCK PC11 ------> SPI3_MISO */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF7_SPI3; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* SPI3 interrupt Init */ HAL_NVIC_SetPriority(SPI3_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI3_IRQn); /* USER CODE BEGIN SPI3_MspInit 1 */ /* USER CODE END SPI3_MspInit 1 */ } else if(spiHandle->Instance==SPI4) { /* USER CODE BEGIN SPI4_MspInit 0 */ /* USER CODE END SPI4_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI4; PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI4 clock enable */ __HAL_RCC_SPI4_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /**SPI4 GPIO Configuration PE2 ------> SPI4_SCK PE5 ------> SPI4_MISO PE6 ------> SPI4_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI4; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SPI4 interrupt Init */ HAL_NVIC_SetPriority(SPI4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI4_IRQn); /* USER CODE BEGIN SPI4_MspInit 1 */ /* USER CODE END SPI4_MspInit 1 */ } else if(spiHandle->Instance==SPI5) { /* USER CODE BEGIN SPI5_MspInit 0 */ /* USER CODE END SPI5_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI5; PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI5 clock enable */ __HAL_RCC_SPI5_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); /**SPI5 GPIO Configuration PF7 ------> SPI5_SCK PF8 ------> SPI5_MISO PF9 ------> SPI5_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI5; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); /* SPI5 interrupt Init */ HAL_NVIC_SetPriority(SPI5_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI5_IRQn); /* USER CODE BEGIN SPI5_MspInit 1 */ /* USER CODE END SPI5_MspInit 1 */ } else if(spiHandle->Instance==SPI6) { /* USER CODE BEGIN SPI6_MspInit 0 */ /* USER CODE END SPI6_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6; PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_D3PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI6 clock enable */ __HAL_RCC_SPI6_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /**SPI6 GPIO Configuration PG12 ------> SPI6_MISO PG13 ------> SPI6_SCK PG14 ------> SPI6_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI6; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /* SPI6 interrupt Init */ HAL_NVIC_SetPriority(SPI6_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI6_IRQn); /* USER CODE BEGIN SPI6_MspInit 1 */ /* USER CODE END SPI6_MspInit 1 */ } } 在stm32h7xx_hal_conf.h文件中,打开宏定义:

#define HAL_SPI_MODULE_ENABLED

在drv_spi.c文件的spi_config数组中用到了SPI6_BUS_CONFIG,默认工程是没有的,需要自己添加,可以参考已有的SPI配置

在spi_config.h文件尾部添加SPI6_BUS_CONFIG

#ifdef BSP_USING_SPI6 #ifndef SPI6_BUS_CONFIG #define SPI6_BUS_CONFIG { .Instance = SPI6, .bus_name = "spi6", } #endif /* SPI6_BUS_CONFIG / #endif /BSP_USING_SPI6 / //#ifdef BSP_SPI6_TX_USING_DMA//#ifndef SPI6_TX_DMA_CONFIG //#define SPI6_TX_DMA_CONFIG // { // .dma_rcc = SPI6_TX_DMA_RCC, // .Instance = SPI6_TX_DMA_INSTANCE, // .channel = SPI6_TX_DMA_CHANNEL, // .dma_irq = SPI6_TX_DMA_IRQ, // } //#endif /SPI6_TX_DMA_CONFIG / //#endif /BSP_SPI6_TX_USING_DMA / // //#ifdef BSP_SPI6_RX_USING_DMA //#ifndef SPI6_RX_DMA_CONFIG //#define SPI6_RX_DMA_CONFIG // { // .dma_rcc = SPI6_RX_DMA_RCC, // .Instance = SPI6_RX_DMA_INSTANCE, // .channel = SPI6_RX_DMA_CHANNEL, // .dma_irq = SPI6_RX_DMA_IRQ, // } //#endif /SPI6_RX_DMA_CONFIG / //#endif /BSP_SPI6_RX_USING_DMA */ 在dfs_fs.c文件中,添加文件系统默认装载表:

const struct dfs_mount_tbl mount_table[] = { {"sd0", "/", "elm", 0, 0}, {0} };

在driver目录下添加drv_spi_tfcard.c文件

测试

至此完成基于SPI的SD驱动框架。

遗留问题 添加SD后,MPU配置会影响以太网ping的效果,使用下面配置SD卡、以太网均正常

{ 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 = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_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_NUMBER1; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /Enables the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } 使用下面的配置,以太网ping不通

{ MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU / HAL_MPU_Disable(); /Configure the MPU attributes as WT for AXI SRAM/ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x24000000; MPU_InitStruct.Size = MPU_REGION_SIZE_512KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0X00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #ifdef BSP_USING_SDRAM /Configure the MPU attributes as WT for SDRAM / MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0xC0000000; MPU_InitStruct.Size = MPU_REGION_SIZE_32MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #endif #ifdef BSP_USING_ETH /Configure the MPU attributes as Device not cacheable for ETH DMA descriptorsand RX Buffers*/ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_32KB; 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_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER2; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #endif /* Configure the MPU attributes as WT for QSPI / // MPU_InitStruct.Enable = MPU_REGION_ENABLE; // MPU_InitStruct.BaseAddress = 0x90000000; // MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; // MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; // MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; // MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; // MPU_InitStruct.Number = MPU_REGION_NUMBER3; // 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); /Enable CACHE */ SCB_EnableICache(); SCB_EnableDCache(); return RT_EOK; }

推荐内容