#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; }