mdio读写接口

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

typedef unsigned long U32;
typedef unsigned short U16;

#define HI_FAILURE (-1)
#define HI_SUCCESS (0)
/*
 * NOTE! This ctype does not handle EOF like the standard C
 * library is required to.
 */

#define _U	0x01	/* upper */
#define _L	0x02	/* lower */
#define _D	0x04	/* digit */
#define _C	0x08	/* cntrl */
#define _P	0x10	/* punct */
#define _S	0x20	/* white space (space/lf/tab) */
#define _X	0x40	/* hex digit */
#define _SP	0x80	/* hard space (0x20) */

unsigned char _ctype[] = {
_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */


#define __ismask(x) (_ctype[(int)(unsigned char)(x)])

#define isalnum(c)	((__ismask(c)&(_U|_L|_D)) != 0)
#define isalpha(c)	((__ismask(c)&(_U|_L)) != 0)
#define iscntrl(c)	((__ismask(c)&(_C)) != 0)
#define isdigit(c)	((__ismask(c)&(_D)) != 0)
#define isgraph(c)	((__ismask(c)&(_P|_U|_L|_D)) != 0)
#define islower(c)	((__ismask(c)&(_L)) != 0)
#define isprint(c)	((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
#define ispunct(c)	((__ismask(c)&(_P)) != 0)
#define isspace(c)	((__ismask(c)&(_S)) != 0)
#define isupper(c)	((__ismask(c)&(_U)) != 0)
#define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)

#define isascii(c) (((unsigned char)(c))<=0x7f)
#define toascii(c) (((unsigned char)(c))&0x7f)

static inline unsigned char __tolower(unsigned char c)
{
	if (isupper(c))
		c -= 'A'-'a';
	return c;
}

static inline unsigned char __toupper(unsigned char c)
{
	if (islower(c))
		c -= 'a'-'A';
	return c;
}

#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)

static U32 atoul(char *str, U32 * pulValue)
{
    U32 ulResult=0;

    while (*str)
    {
        if (isdigit((int)*str))
        {
            /*最大支持到0xFFFFFFFF(4294967295), 
               X * 10 + (*str)-48 <= 4294967295
               所以, X = 429496729 */
            if ((ulResult<429496729) || ((ulResult==429496729) && (*str<'6')))
            {
                ulResult = ulResult*10 + (*str)-48;
            }
            else
            {
                *pulValue = ulResult;
                return HI_FAILURE;
            }
        }
        else
        {
            *pulValue=ulResult;
            return HI_FAILURE;
        }
        str++;
    }
    *pulValue=ulResult;
    return HI_SUCCESS;
}


#define ASC2NUM(ch) (ch - '0')
#define HEXASC2NUM(ch) (ch - 'A' + 10)

static unsigned long  atoulx(char *str, U32 * pulValue)
{
    U32   ulResult=0;
    unsigned char ch;

    while (*str)
    {
        ch=toupper(*str);
        if (isdigit(ch) || ((ch >= 'A') && (ch <= 'F' )))
        {
            if (ulResult < 0x10000000)
            {
                ulResult = (ulResult << 4) + ((ch<='9')?(ASC2NUM(ch)):(HEXASC2NUM(ch)));
            }
            else
            {
                *pulValue=ulResult;
                return HI_FAILURE;
            }
        }
        else
        {
            *pulValue=ulResult;
            return HI_FAILURE;
        }
        str++;
    }
    
    *pulValue=ulResult;
    return HI_SUCCESS;
}

static unsigned long StrToNumber(char *str , U32 * pulValue)
{
    /*判断是否16进制的字符串*/
    if ( *str == '0' && (*(str+1) == 'x' || *(str+1) == 'X') )
    {
        if (*(str+2) == '\0')
        {
            return HI_FAILURE;
        }
        else
        {
            return atoulx(str+2,pulValue);
        }
    }
    else
    {
        return atoul(str,pulValue);
    }
}

#define READ(_a)     ( *((U32*)(_a)) )
#define WRITE(_a, _v)   (*(volatile U32 *)(_a) = (_v))

#define ALLOC_SIZE 1024
static int g_fd = -1;
static void *map_base = NULL;

#if defined _HI3536_

#define MDIO_BASE 0x11020000
#define MDIO_DATA 0X0014
#define MDIO_ADDR 0X0010
#define MII_BUSY  0x00000001
#define MII_WRITE 0x00000002
#define MII_PHY   0x04


static int mdio_write(int phyaddr, int phyreg, U16 phydata)
{
    U16 value = 0;
	value = (((phyaddr << 11) & (0x0000F800)) |
		    ((phyreg << 6) & (0x000007C0))) |
		    MII_WRITE;
	value |= MII_BUSY;
	do {} while (((READ(map_base + MDIO_ADDR)) & MII_BUSY) == 1);
	/* Set the MII address register to write */
	WRITE(map_base + MDIO_DATA, phydata);
	WRITE(map_base + MDIO_ADDR, value);

	/* Wait until any existing MII operation is complete */
	do {} while (((READ(map_base + MDIO_ADDR)) & MII_BUSY) == 1);
    return 0;
}

static int mdio_read(int phyaddr, int phyreg)
{   
    int data = -1;
    U16 value = 0;
    
	value = (((phyaddr << 11) & (0x0000F800)) |
		    ((phyreg << 6) & (0x000007C0)));
	value |= MII_BUSY;
	do {} while (((READ(map_base + MDIO_ADDR)) & MII_BUSY) == 1);
	/* Set the MII address register to write */
	WRITE(map_base + MDIO_ADDR, value);
	/* Wait until any existing MII operation is complete */
	do {} while (((READ(map_base + MDIO_ADDR)) & MII_BUSY) == 1);

    data = READ(map_base + MDIO_DATA);
    
    return data;
}
#else

#define MDIO_BASE 0xF9841000
#define MDIO_DATA (map_base + 0X03C4)
#define MDIO_ADDR (map_base + 0X03C0)
#define MDIO_STAT (map_base + 0X03D0)
#define MII_PHY   0x04

#define test_mdio_ready(stat) ({ \
				unsigned long _bits_desc = 0x140001; \
				unsigned long _shift = (_bits_desc) >> 16; \
				unsigned long _mask = ((_bits_desc & 0x3F) < 32) ? (((1 << (_bits_desc & 0x3F)) - 1) << (_shift)) : 0xffffffff; \
				(READ(stat) & _mask) >> (_shift); })

#define test_mdio_read_data_done(stat) ({ \
			unsigned long _bits_desc = 0x1; \
			unsigned long _shift = (_bits_desc) >> 16; \
			unsigned long _mask = ((_bits_desc & 0x3F) < 32) ? (((1 << (_bits_desc & 0x3F)) - 1) << (_shift)) : 0xffffffff; \
            (READ(stat) & _mask) >> (_shift); })

static int wait_mdio_ready()
{
	int timeout_us = 1000;

	while (--timeout_us && !test_mdio_ready(MDIO_ADDR) == 0)
		usleep(10);

	return timeout_us;
}

static void mdio_start_phyread(unsigned char phy,unsigned char reg)
{
	WRITE(MDIO_ADDR, 0);
	WRITE(MDIO_ADDR, (phy<<8)|(reg<<0)|(0x2<<16)|(0x01<<20));
}

static int mdio_read(int phyaddr, int phyreg)
{
	int data = 0;
	int timeout = 100;
	
	if (!wait_mdio_ready())
		return -1;
	mdio_start_phyread(phyaddr, phyreg);
	while (!wait_mdio_ready() && timeout-- > 0)
	{
        usleep(5*1000);
	}
	if (timeout <= 0 || !test_mdio_read_data_done(MDIO_STAT)==0)
	{
        data = 0;
    	/* it should return Error(-1), but miiphy_read() will
        	 * print error info, it's annoying
        	 */
    	return data;
	}
		
	data = READ(MDIO_DATA)>>16;
	return data;
}

static int mdio_write(int phyaddr, int phyreg, U16 phydata)
{
	if (!wait_mdio_ready())
			return -1;
	WRITE(MDIO_DATA, phydata);
	WRITE(MDIO_ADDR, 0);
	WRITE(MDIO_ADDR, (phyaddr<<8)|(phyreg<<0)|(0x1<<16)|(0x01<<20));
	return 0;
}

#endif
static int phy_map()
{
    if (g_fd < 0)
    {
        g_fd = open("/dev/mem", O_RDWR | O_SYNC);  
        if (g_fd < 0) 
        {  
            printf("Fail to open /dev/mem fd=%08x\n", g_fd);
            return HI_FAILURE;
        }
    }
    map_base = mmap(0, ALLOC_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, g_fd, MDIO_BASE);
    if (!map_base)
    {
        printf("mmap phyaddr %#x failed ! \n", MDIO_BASE);
        close(g_fd);
        g_fd = -1;
        return HI_FAILURE;
    }

    return HI_SUCCESS;
}

static void phy_umap()
{
    if (map_base)
        munmap(map_base, ALLOC_SIZE);

    if (g_fd > 0)
        close(g_fd);

    map_base = NULL;
    g_fd = -1;
}


int main(int argc, char **argv)
{
    U32 addr = 0;
    U32 value = 0;
    
    if (argc <= 1 || argc > 3)
    {
        printf("usage: %s <address>. sample: %s 0x80040000 \n", argv[0], argv[0]);
        return -1;
    }
    if (phy_map() == HI_FAILURE)
    {
        return -1;
    }

    if (argc == 2)
    {
        StrToNumber(argv[1], &addr);
        value = mdio_read(MII_PHY, addr);
        printf("read value = %#x\n", value);
    }

    if (argc == 3)
    {
        StrToNumber(argv[1], &addr);
        StrToNumber(argv[2], &value);
        mdio_write(MII_PHY, addr, value);        
        printf("write value = %#x\n", mdio_read(MII_PHY, addr));
    }

    phy_umap();
    
    return 0;
}



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值