Skip to content

Instantly share code, notes, and snippets.

@michalpelka
Last active March 29, 2018 08:14
Show Gist options
  • Save michalpelka/6d6043502309f7bf064c5b90601f2ca5 to your computer and use it in GitHub Desktop.
Save michalpelka/6d6043502309f7bf064c5b90601f2ca5 to your computer and use it in GitHub Desktop.

Resolved problems

Cheap shit-like ST-link 💩

  • In Debug Configuration please set 'Reset Mode' to value 'Software System Reset'

KSZ8863FLL

  • Generate code in CubeMX for PHY with RMII.
  • Override RMII config in section:
/* USER CODE BEGIN MACADDRESS */
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
heth.Init.Speed = ETH_SPEED_100M;
heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
heth.Init.PhyAddress = 0xFF;
/* USER CODE END MACADDRESS */
  • Disable PHY initialization inside HAL library (HAL_ETH_Init(&heth)) by commenting out Phy reset, autonegotation
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{
  uint32_t tmpreg1 = 0U, phyreg = 0U;
  uint32_t hclk = 60000000U;
  uint32_t tickstart = 0U;
  uint32_t err = ETH_SUCCESS;

  /* Check the ETH peripheral state */
  if(heth == NULL)
  {
    return HAL_ERROR;
  }

  /* Check parameters */
  assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
  assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
  assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
  assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));  

  if(heth->State == HAL_ETH_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    heth->Lock = HAL_UNLOCKED;
    /* Init the low level hardware : GPIO, CLOCK, NVIC. */
    HAL_ETH_MspInit(heth);
  }

  /* Select MII or RMII Mode*/
  AFIO->MAPR &= ~(AFIO_MAPR_MII_RMII_SEL);
  AFIO->MAPR |= (uint32_t)heth->Init.MediaInterface;

  /* Ethernet Software reset */
  /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
  /* After reset all the registers holds their respective reset values */
  (heth->Instance)->DMABMR |= ETH_DMABMR_SR;

  /* Get tick */
  tickstart = HAL_GetTick();

  /* Wait for software reset */
  while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_SWRESET)
    {     
      heth->State= HAL_ETH_STATE_TIMEOUT;

      /* Process Unlocked */
      __HAL_UNLOCK(heth);

      /* Note: The SWR is not performed if the ETH_RX_CLK or the ETH_TX_CLK are  
         not available, please check your external PHY or the IO configuration */
      return HAL_TIMEOUT;
    }
  }

  /*-------------------------------- MAC Initialization ----------------------*/
  /* Get the ETHERNET MACMIIAR value */
  tmpreg1 = (heth->Instance)->MACMIIAR;
  /* Clear CSR Clock Range CR[2:0] bits */
  tmpreg1 &= ETH_MACMIIAR_CR_MASK;

  /* Get hclk frequency value */
  hclk = HAL_RCC_GetHCLKFreq();

  /* Set CR bits depending on hclk value */
  if((hclk >= 20000000U)&&(hclk < 35000000U))
  {
    /* CSR Clock Range between 20-35 MHz */
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV16;
  }
  else if((hclk >= 35000000U)&&(hclk < 60000000U))
  {
    /* CSR Clock Range between 35-60 MHz */
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV26;
  }  
  else
  {
    /* CSR Clock Range between 60-72 MHz */
    tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_DIV42;
  }  

  /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
  (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1;

  /*-------------------- PHY initialization and configuration ----------------*/
  /* Put the PHY in reset mode */
//  if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK)
//  {
//    /* In case of write timeout */
//    err = ETH_ERROR;
//
//    /* Config MAC and DMA */
//    ETH_MACDMAConfig(heth, err);
//
//    /* Set the ETH peripheral state to READY */
//    heth->State = HAL_ETH_STATE_READY;
//
//    /* Return HAL_ERROR */
//    return HAL_ERROR;
//  }
//
//  /* Delay to assure PHY reset */
//  HAL_Delay(PHY_RESET_DELAY);
//
//  if((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
//  {
//    /* Get tick */
//    tickstart = HAL_GetTick();
//
//    /* We wait for linked status */
//    do
//    {
//      HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
//
//      /* Check for the Timeout */
//      if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_LINKED_STATE)
//      {
//        /* In case of write timeout */
//        err = ETH_ERROR;
//
//        /* Config MAC and DMA */
//        ETH_MACDMAConfig(heth, err);
//
//        heth->State= HAL_ETH_STATE_READY;
//
//        /* Process Unlocked */
//        __HAL_UNLOCK(heth);
//
//        return HAL_TIMEOUT;
//      }
//    } while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));
//
//
//    /* Enable Auto-Negotiation */
//    if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK)
//    {
//      /* In case of write timeout */
//      err = ETH_ERROR;
//
//      /* Config MAC and DMA */
//      ETH_MACDMAConfig(heth, err);
//
//      /* Set the ETH peripheral state to READY */
//      heth->State = HAL_ETH_STATE_READY;
//
//      /* Return HAL_ERROR */
//      return HAL_ERROR;
//    }
//
//    /* Get tick */
//    tickstart = HAL_GetTick();
//
//    /* Wait until the auto-negotiation will be completed */
//    do
//    {
//      HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
//
//      /* Check for the Timeout */
//      if((HAL_GetTick() - tickstart ) > ETH_TIMEOUT_AUTONEGO_COMPLETED)
//      {
//        /* In case of write timeout */
//        err = ETH_ERROR;
//
//        /* Config MAC and DMA */
//        ETH_MACDMAConfig(heth, err);
//
//        heth->State= HAL_ETH_STATE_READY;
//
//        /* Process Unlocked */
//        __HAL_UNLOCK(heth);
//
//        return HAL_TIMEOUT;
//      }
//
//    } while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
//
//    /* Read the result of the auto-negotiation */
//    if((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK)
//    {
//      /* In case of write timeout */
//      err = ETH_ERROR;
//
//      /* Config MAC and DMA */
//      ETH_MACDMAConfig(heth, err);
//
//      /* Set the ETH peripheral state to READY */
//      heth->State = HAL_ETH_STATE_READY;
//
//      /* Return HAL_ERROR */
//      return HAL_ERROR;
//    }
//
//    /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
//    if((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
//    {
//      /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
//      (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX;
//    }
//    else
//    {
//      /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
//      (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX;
//    }
//    /* Configure the MAC with the speed fixed by the auto-negotiation process */
//    if((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS)
//    {
//      /* Set Ethernet speed to 10M following the auto-negotiation */
//      (heth->Init).Speed = ETH_SPEED_10M;
//    }
//    else
//    {
//      /* Set Ethernet speed to 100M following the auto-negotiation */
//      (heth->Init).Speed = ETH_SPEED_100M;
//    }
//  }
//  else /* AutoNegotiation Disable */
//  {
//    /* Check parameters */
//    assert_param(IS_ETH_SPEED(heth->Init.Speed));
//    assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
//
//    /* Set MAC Speed and Duplex Mode */
//    if(HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3U) |
//                                                (uint16_t)((heth->Init).Speed >> 1U))) != HAL_OK)
//    {
//      /* In case of write timeout */
//      err = ETH_ERROR;
//
//      /* Config MAC and DMA */
//      ETH_MACDMAConfig(heth, err);
//
//      /* Set the ETH peripheral state to READY */
//      heth->State = HAL_ETH_STATE_READY;
//
//      /* Return HAL_ERROR */
//      return HAL_ERROR;
//    }
//
//    /* Delay to assure PHY configuration */
//    HAL_Delay(PHY_CONFIG_DELAY);
//  }
//
  /* Config MAC and DMA */
  ETH_MACDMAConfig(heth, err);

  /* Set ETH HAL State to Ready */
  heth->State= HAL_ETH_STATE_READY;

  /* Return function status */
  return HAL_OK;
}
  • Voila, should be able to ping board!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment