[KSZ8081RND] wip: add driver for testing

This commit is contained in:
ІО-23 Шмуляр Олег 2025-05-10 13:04:31 +03:00
parent 6b38f3945e
commit 3d2f391749
4 changed files with 198 additions and 5 deletions

13
Core/Inc/KSZ8081RND.h Normal file
View File

@ -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

177
Core/Src/KSZ8081RND.c Normal file
View File

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

View File

@ -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();

View File

@ -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);