我是靠谱客的博主 结实翅膀,最近开发中收集的这篇文章主要介绍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) == '')
{
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=%08xn", 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 = %#xn", value);
}
if (argc == 3)
{
StrToNumber(argv[1], &addr);
StrToNumber(argv[2], &value);
mdio_write(MII_PHY, addr, value);
printf("write value = %#xn", mdio_read(MII_PHY, addr));
}
phy_umap();
return 0;
}

最后

以上就是结实翅膀为你收集整理的mdio读写接口的全部内容,希望文章能够帮你解决mdio读写接口所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部