From 3d2f391749c2ddeb3954154821f6435a38ccc5cf Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Sat, 10 May 2025 13:04:31 +0300 Subject: [PATCH] [KSZ8081RND] wip: add driver for testing --- Core/Inc/KSZ8081RND.h | 13 +++ Core/Src/KSZ8081RND.c | 177 +++++++++++++++++++++++++++++++++++ Core/Src/main.c | 7 +- Core/Src/stm32f4xx_hal_msp.c | 6 +- 4 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 Core/Inc/KSZ8081RND.h create mode 100644 Core/Src/KSZ8081RND.c diff --git a/Core/Inc/KSZ8081RND.h b/Core/Inc/KSZ8081RND.h new file mode 100644 index 0000000..0bfe091 --- /dev/null +++ b/Core/Inc/KSZ8081RND.h @@ -0,0 +1,13 @@ +#ifndef __KSZ8081RND +#define __KSZ8081RND + + +int KSZ8081RND_run_test(void); + +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t *pRegValue); +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t RegValue); + + +#endif diff --git a/Core/Src/KSZ8081RND.c b/Core/Src/KSZ8081RND.c new file mode 100644 index 0000000..5bfba10 --- /dev/null +++ b/Core/Src/KSZ8081RND.c @@ -0,0 +1,177 @@ +#include "main.h" +#include "lcd.h" +#include "KSZ8081RND.h" + +#define ETH_MACMIIAR_CR_MASK 0xFFFFFFE3U + +extern TIM_HandleTypeDef htim2; + +int KSZ8081RND_run_test(void) +{ + DISPLAY_CLEAR; + display_write_data_seq("KSZ8081RND ETH"); + DISPLAY_SET_CURSOR(1, 4); + + // enable clocks + __HAL_RCC_ETH_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + // configure pins + GPIO_InitTypeDef GPIO_InitStruct = {}; + + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + // hardware reset KSZ8081RND + HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_RESET); + HAL_Delay(10); + HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_SET); + HAL_Delay(10); + + // enable PLL and REF_CLK output from KSZ8081RND + ETH_HandleTypeDef heth; + heth.Instance = ETH; + heth.Init.MediaInterface = HAL_ETH_RMII_MODE; + + HAL_StatusTypeDef s; + uint32_t r; + + s = HAL_ETH_ReadPHYRegister(&heth, 0x0, 0x1F, &r); + switch (s) { + case HAL_OK: + // ok + break; + case HAL_ERROR: + display_write_data_seq("R ERROR"); + return 1; + case HAL_BUSY: + display_write_data_seq("R BUSY"); + return 1; + case HAL_TIMEOUT: + display_write_data_seq("R TIMEOUT"); + return 1; + } + + r |= (1 << 7); + s = HAL_ETH_WritePHYRegister(&heth, 0x0, 0x1F, r); + switch (s) { + case HAL_OK: + // ok + break; + case HAL_ERROR: + display_write_data_seq("W ERROR"); + return 1; + case HAL_BUSY: + display_write_data_seq("W BUSY"); + return 1; + case HAL_TIMEOUT: + display_write_data_seq("W TIMEOUT"); + return 1; + } + + // enable RMII interface + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL); + SYSCFG->PMC |= (uint32_t)heth.Init.MediaInterface; + (void)SYSCFG->PMC; + + // check if software reset happens on MAC + TIM2->CNT = 0; + + ETH->DMABMR |= 1; // assert software reset + HAL_TIM_Base_Start(&htim2); + + while (ETH->DMABMR & 1) { + if (TIM2->CNT > (500000 << 4)) { + // MAC software reset timed out -> no REF_CLK output? + HAL_TIM_Base_Stop(&htim2); + return 1; + } + } + + HAL_TIM_Base_Stop(&htim2); + return 0; +} + +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t *pRegValue) +{ + uint32_t tmpreg1; + uint32_t tickstart; + + tmpreg1 = heth->Instance->MACMIIAR; + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + tmpreg1 |= ((PHYAddr << 11U) & ETH_MACMIIAR_PA); + tmpreg1 |= (((uint32_t)PHYReg << 6U) & ETH_MACMIIAR_MR); + tmpreg1 &= ~ETH_MACMIIAR_MW; + tmpreg1 |= ETH_MACMIIAR_MB; + + heth->Instance->MACMIIAR = tmpreg1; + + tickstart = HAL_GetTick(); + + while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + { + if ((HAL_GetTick() - tickstart) > PHY_READ_TO) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + *pRegValue = (uint16_t)(heth->Instance->MACMIIDR); + + return HAL_OK; +} + +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, uint32_t RegValue) +{ + uint32_t tmpreg1; + uint32_t tickstart; + + tmpreg1 = heth->Instance->MACMIIAR; + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + tmpreg1 |= (((uint32_t)PHYReg << 6U) & (0x1FUL << (6U))); + tmpreg1 |= 3; + + heth->Instance->MACMIIDR = (uint16_t)RegValue; + heth->Instance->MACMIIAR = tmpreg1; + + tickstart = HAL_GetTick(); + + while ((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + { + if ((HAL_GetTick() - tickstart) > PHY_WRITE_TO) + { + return HAL_ERROR; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + return HAL_OK; +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 6612dcd..0d65ba8 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -34,6 +34,7 @@ #include "MP45DT02.h" #include "LSM9DS1.h" #include "DHT11.h" +#include "KSZ8081RND.h" /* USER CODE END Includes */ @@ -96,7 +97,8 @@ static const int ((*executors[])(void)) = { MP45DT02_run_test, LSM9DS1_test_accel, LSM9DS1_test_magnet, - DHT11_run_test + DHT11_run_test, + KSZ8081RND_run_test }; static const void ((*cleanup_functions[])(void)) = { @@ -109,6 +111,7 @@ static const void ((*cleanup_functions[])(void)) = { NULL, LSM9DS1_cleanup_accel, NULL, + NULL, NULL }; @@ -168,7 +171,7 @@ int main(void) MX_TIM2_Init(); MX_ETH_Init(); /* USER CODE BEGIN 2 */ -back_to_life: + GPIOD->BSRR = 0x1000; display_init(); diff --git a/Core/Src/stm32f4xx_hal_msp.c b/Core/Src/stm32f4xx_hal_msp.c index bd83ab8..3266ddf 100644 --- a/Core/Src/stm32f4xx_hal_msp.c +++ b/Core/Src/stm32f4xx_hal_msp.c @@ -194,11 +194,11 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef* heth) /* USER CODE BEGIN ETH_MspInit 1 */ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_RESET); - HAL_Delay(200); + HAL_Delay(10); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET); - HAL_Delay(200); + HAL_Delay(10); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_SET); - HAL_Delay(200); + HAL_Delay(10); uint32_t r; HAL_ETH_ReadPHYRegister(heth, 0x0, 0x1F, &r);