mdio.c
#include "mdio.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "gd32e50x.h"
#include "systick.h"
/* MDIO发送一个bit的数据,MDIO必须已经被配置为输出 */
void yt8531_ModeSet(void)//011
{
gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
//set mode 110 fiber auto
gpio_bit_set(GPIOD, GPIO_PIN_14|GPIO_PIN_13);
gpio_bit_reset(GPIOD, GPIO_PIN_15);
}
void yt8531s_ext_write(uint8_t phyaddr, uint16_t regaddr, uint16_t data)
{
yt8531_mdio_write(phyaddr,0x1e,regaddr);
yt8531_mdio_write(phyaddr,0x1f,data);
}
uint16_t yt8531s_ext_read(uint8_t phyaddr, uint16_t regaddr)
{
uint16_t data=0;
yt8531_mdio_write(phyaddr,0x1e,regaddr);
data=yt8531_mdio_read(phyaddr,0x1f);
return data;
}
//set MDIO val
void set_mdio_val_bit(uint8_t val)
{
if( (val&0x1) == 0)
gpio_bit_reset(GPIOE, MDIO_Pin);
else
gpio_bit_set(GPIOE, MDIO_Pin);
}
static void mdio_bb_send_bit(uint8_t val)
{
MDC_L();
set_mdio_val_bit(val);
delay_us(1);
MDC_H();
delay_us(1);
// set_mdc_val();
}
/* MDIO 获取一个bit的数据,MDIO必须已经被配置为输入. */
static void mdio_bb_get_bit(uint8_t *pb)
{
MDC_L();
delay_us(1);
*(pb) = (uint8_t)GET_MDIO();
MDC_H();
delay_us(1);
}
uint16_t yt8531_mdio_read(uint8_t phyaddr, uint8_t regaddr)
{
uint16_t data = 0;
int i;
uint8_t b;
gpio_init(GPIOE, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MDIO_Pin);
//Preamble
for(i=0;i<32;i++)
{
mdio_bb_send_bit(1);
}
//Start
mdio_bb_send_bit(0);
mdio_bb_send_bit(1);
//OP code
mdio_bb_send_bit(1);
mdio_bb_send_bit(0);
//phy address
for(i=0;i<5;i++)
{
if(phyaddr&(0x10>>i))
mdio_bb_send_bit(1);
else
mdio_bb_send_bit(0);
}
//reg address
for(i=0;i<5;i++)
{
if(regaddr&(0x10>>i))
mdio_bb_send_bit(1);
else
mdio_bb_send_bit(0);
}
//set
gpio_init(GPIOE, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, MDIO_Pin);
//ack
mdio_bb_get_bit(&b);
mdio_bb_get_bit(&b);
//data
for(i=0;i<16;i++)
{
data <<= 1;
mdio_bb_get_bit(&b);
if(b)
data |= 0x01;
}
return data;
}
void yt8531_mdio_write(uint8_t phyaddr, uint8_t regaddr, uint16_t data)
{
int i;
gpio_init(GPIOE, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MDIO_Pin);
//Preamble
for(i=0;i<32;i++)
{
mdio_bb_send_bit(1);
}
//Start
mdio_bb_send_bit(0);
mdio_bb_send_bit(1);
//OP code
mdio_bb_send_bit(0);
mdio_bb_send_bit(1);
//phy address
for(i=0;i<5;i++)
{
if(phyaddr&(0x10>>i))
mdio_bb_send_bit(1);
else
mdio_bb_send_bit(0);
}
//reg address
for(i=0;i<5;i++)
{
if(regaddr&(0x10>>i))
mdio_bb_send_bit(1);
else
mdio_bb_send_bit(0);
}
//ack
mdio_bb_send_bit(1);
mdio_bb_send_bit(0);
//data
for(i=0;i<16;i++)
{
if(data&(0x8000>>i))
mdio_bb_send_bit(1);
else
mdio_bb_send_bit(0);
}
}
void delay(void)
{
delay_us(1);
}
void yt8531_mdio_init(void)
{
//rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOE);
//开漏输出
//MDIO---PE15 MDC---PE14
gpio_init(GPIOE, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MDIO_Pin);
gpio_init(GPIOE, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MDC_Pin);
}
mdio.h
#ifndef __MDIO_H_
#define __MDIO_H_
#include "gd32e50x.h"
//pyh_addr
#define YT8531_MDIO_ADDR 0x0
#define BCM81381_MDIO_ADDR 0x2 //00010---5bit
//dev_addr
#define BCM81381_DEV_ADDR 0x1 //00001---5bit
#define MDC_Pin GPIO_PIN_14
#define MDC_GPIO_Port GPIOE
#define MDIO_Pin GPIO_PIN_15
#define MDIO_GPIO_Port GPIOE
//MDC---PC1
#define MDC_H() gpio_bit_set(GPIOE, GPIO_PIN_14 )
#define MDC_L() gpio_bit_reset(GPIOE, GPIO_PIN_14 )
//get pin value
#define GET_MDIO() gpio_input_bit_get(GPIOE, GPIO_PIN_15)
void yt8531s_ext_write(uint8_t phyaddr, uint16_t regaddr, uint16_t data);
uint16_t yt8531s_ext_read(uint8_t phyaddr, uint16_t regaddr);
void yt8531_mdio_init(void);
uint16_t yt8531_mdio_read(uint8_t phyaddr, uint8_t regaddr);
void yt8531_mdio_write(uint8_t phyaddr, uint8_t regaddr, uint16_t data);
void yt8531_ModeSet(void);
/*uint16_t read_data(uint8_t phy, uint8_t dev, uint16_t reg);
void write_data(uint8_t phy, uint8_t dev, uint16_t reg, uint16_t value);
unsigned int bcm81381_mdio_get_chip_type(void);*/
#endif
根据需要自取。