⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds2411.cpp

📁 DS2411是DALLAS公司的电子序列号芯片
💻 CPP
字号:
/******************************************************************************

        

 ******************************************************************************
  文 件 名   : ds2411.cpp
  版 本 号   : 初稿
  作    者   : liqin
  生成日期   : 2007年6月23日
  最近修改   :
  功能描述   : 实现DS2411的读写控制功能。
  函数列表   :
  修改历史   :
  1.日    期   : 2007年6月23日
    作    者   : liqin
    修改内容   : 创建文件

******************************************************************************/
#include "../include/ds2411.h"

#if 1
/*****************************************************************************
 函 数 名  : EM85xx_WriteReg
 功能描述  : 写EM85xx的寄存器
 输入参数  : unsigned long Reg   
             unsigned long Data  
 输出参数  : 无
 返 回 值  : static void
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2007年5月25日
    作    者   : Sean Tang
    修改内容   : 新生成函数

*****************************************************************************/
static void EM85xx_WriteReg (unsigned long Reg, unsigned long Data)
{
	*((volatile unsigned long *)Reg) = Data;
}

/*****************************************************************************
 函 数 名  : EM85xx_ReadReg
 功能描述  : 读EM85xx的寄存器
 输入参数  : unsigned long Reg  
 输出参数  : 无
 返 回 值  : static unsigned long
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2007年5月25日
    作    者   : Sean Tang
    修改内容   : 新生成函数

*****************************************************************************/
static unsigned long EM85xx_ReadReg (unsigned long Reg)
{
	return *((volatile unsigned long *)(Reg));
}

/*****************************************************************************
 函 数 名  : EM85xxI2C__Write
 功能描述  : I2C的写入函数
 输入参数  : unsigned long devaddr  
             unsigned long adr      
             unsigned char *pData   
             int n                  
 输出参数  : 无
 返 回 值  : static int
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2007年5月25日
    作    者   : Sean Tang
    修改内容   : 新生成函数

*****************************************************************************/
static int EM85xxI2C__Write (unsigned long devaddr, unsigned long adr, 
									unsigned char *pData, int n)
{
	int i;
	EM85xx_WriteReg (I2C_MASTER_CONFIG_V, 0xF8);
	EM85xx_WriteReg (I2C_MASTER_CLK_DIV_V, CLK_DIV);	// assume 150mhz clock (375=750/2)
	EM85xx_WriteReg (I2C_MASTER_DEV_ADDR_V, devaddr >> 1);

	// ready for a command
	// XXX bug: we really should have a timeout here
	while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 1) == 0);

	// write
	for (i = 0; i < n; i++)
	{
		//printk("0x%x", *pData);
		EM85xx_WriteReg (I2C_MASTER_ADR_V, adr++);
		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT_V, 0);
		EM85xx_WriteReg (I2C_MASTER_DATAOUT_V, *pData++);
		EM85xx_WriteReg (I2C_MASTER_STARTXFER_V, 0);
		// XXX bug: we really should have a timeout here
		while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 2) == 0);
		DelayUs(2000);
	}	
	return 1;
}

/*****************************************************************************
 函 数 名  : EM85xxI2C__Read
 功能描述  : I2C的读函数
 输入参数  : unsigned long devaddr  
             unsigned long adr      
             unsigned char *pData   
             int n                  
 输出参数  : 无
 返 回 值  : static int
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2007年5月25日
    作    者   : Sean Tang
    修改内容   : 新生成函数

*****************************************************************************/
static int EM85xxI2C__Read (unsigned long devaddr, unsigned long adr,
									unsigned char *pData, int n)
{
	int i;	
	EM85xx_WriteReg (I2C_MASTER_CLK_DIV_V, CLK_DIV);
	
	// ready for a command
	// XXX bug: we really should have a timeout here
	while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 1) == 0);

	for (i = 0; i < n; i++)
	{
		EM85xx_WriteReg (I2C_MASTER_CONFIG_V, 0xFA);
		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT_V, 0);
		EM85xx_WriteReg (I2C_MASTER_DEV_ADDR_V, devaddr >> 1);
		EM85xx_WriteReg	(I2C_MASTER_DATAOUT_V, adr++);		
		EM85xx_WriteReg	(I2C_MASTER_STARTXFER_V, 0 | 0x4);
		// XXX bug: we really should have a timeout here
		while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 2) == 0);
		while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 1) == 0);

		EM85xx_WriteReg (I2C_MASTER_CONFIG_V, 0xFA);
		EM85xx_WriteReg (I2C_MASTER_BYTE_CNT_V, 0);		
		EM85xx_WriteReg (I2C_MASTER_DEV_ADDR_V, devaddr >> 1);	
		EM85xx_WriteReg (I2C_MASTER_STARTXFER_V, 1);

		// XXX bug: we really should have a timeout here
		while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 4) == 1);
		while ((EM85xx_ReadReg (I2C_MASTER_STATUS_V) & 1) == 0);

		*pData = EM85xx_ReadReg (I2C_MASTER_DATAIN_V);
		//printk("0x%x", *pData);
		pData++;
		DelayUs(2000);
	}
	return 1;
}
#endif
/* END:   Added by liqin, 2007/7/11 */


void InitGPIO(void)
{
	//Disable中断
	CPU_WR_32BIT_REG(PIO0_BASE, PIO_INTEN_REG_OFFSET, MAKE_PIOREG(1, 0));

	//初始化极性,全部不反向
	CPU_WR_32BIT_REG(PIO0_BASE, PIO_POL_REG_OFFSET, MAKE_PIOREG(1, 0));

	//初始化方向,全部设置为输出
	CPU_WR_32BIT_REG(PIO0_BASE, PIO_DIR_REG_OFFSET, MAKE_PIOREG(1, 1));

	//初始化GPIO口上的数据,全部设置为'0'
	CPU_WR_32BIT_REG(PIO0_BASE, PIO_DATA_REG_OFFSET, MAKE_PIOREG(1, 0));
}


void SetGPIODirection(UINT32 Base, UINT8 Bit, GPIO_DIR_ENUM Dir)
{
	if ( GPIO_IN == Dir)
	{
	    (*(volatile unsigned int*)(Base + PIO_DIR_REG_OFFSET)) = MAKE_PIOREG(Bit, 0);
	}
	else
	{
	    (*(volatile unsigned int*)(Base + PIO_DIR_REG_OFFSET)) = MAKE_PIOREG(Bit, 1);
	}
}

void WriteGPIOBit(UINT32 Base, UINT8 Bit, UINT16 Value)
{
 	SetGPIODirection(Base, Bit, GPIO_OUT);
	CPU_WR_32BIT_REG(Base, PIO_DATA_REG_OFFSET, MAKE_PIOREG(Bit, Value));
}

UINT16 ReadGPIOBit(UINT32 Base, UINT8 Bit)
{
	UINT16 ret = 0;

	SetGPIODirection(Base, Bit, GPIO_IN);
	ret = *(volatile unsigned int *)(Base + PIO_DATA_REG_OFFSET);
	return ((ret >> Bit) & 0x0001);
}


UINT16 OWReset(void)
{
	UINT16 result = 0;

	//先将端口拉低480us,再拉高,等70us后采样响应信号
	WriteGPIOBit(PIO0_BASE, 1, 0);
	DelayUs(u32ResetLow);
	WriteGPIOBit(PIO0_BASE, 1, 1);
	DelayUs(u32WaitResetAck);
	result	= ReadGPIOBit(PIO0_BASE, 1);

	//等待复位周期完成
	DelayUs(u32FinishReset);

	return result;
}

void OWWriteBit(UINT16 value)
{
	if ( value )
	{
	    //写'1'操作,先拉低,然后拉高完成时序和恢复
	    WriteGPIOBit(PIO0_BASE, 1, 0);
		DelayUs(u32WriteOneLow);
		WriteGPIOBit(PIO0_BASE, 1, 1);
		DelayUs(u32WriteOneHigh);
	}
	else
	{
		//写'0'操作,拉低并保持到时序结束,然后释放总线,留足恢复时间
		WriteGPIOBit(PIO0_BASE, 1, 0);
		DelayUs(u32WriteZeroLow);
		WriteGPIOBit(PIO0_BASE, 1, 1);
		DelayUs(u32WriteZeroHigh);
	}
}


UINT16 OWReadBit(void)
{
	UINT16 result = 0;

	//读时序,拉低后数个us,并在时隙开始后15us内采样端口数据
	WriteGPIOBit(PIO0_BASE, 1, 0);
	DelayUs(u32ReadLow);
	WriteGPIOBit(PIO0_BASE, 1, 1);
	DelayUs(u32ReadBeforSample);

	result = ReadGPIOBit(PIO0_BASE, 1);
	DelayUs(u32FinishRead);
	return result;
}

void OWWriteByte(UINT8 value)
{
	UINT8	i 		= 0;
	UINT8	tmpData	= 0;

	tmpData = value;

	//用循环和移位完成每一位的写操作,从LS开始
	for ( i = 0 ; i < 8; i++ )
	{
	    OWWriteBit(tmpData & 0x01);
		tmpData >>= 1;
	}
}

UINT8 OWReadByte(void)
{
	UINT8	i 		= 0;
	UINT8	result	= 0;

	for ( i = 0 ; i < 8 ; i++ )
	{
		//从低位开始读起,每读一位变向右移动一位
	    result >>= 1;

		if ( OWReadBit())
		{
			//printf("read bit %d is 1 ===", i);
		    result |= 0x80;
		}
		else
		{
			//printf("read bit %d is 0 ===", i);
		}
		DelayUs(3);
	}

	return result;
}




/*****************************************************************************
 函 数 名  : GetSerialNum
 功能描述  : 读取2411的参数。
 输入参数  : SN * pSn  存放参数的结构体指针
 输出参数  : 无
 返 回 值  : BOOL	V_TRUE   :获取成功
 					V_FALSE  :获取失败
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2007年6月23日
    作    者   : liqin
    修改内容   : 新生成函数

*****************************************************************************/
BOOL GetSerialNum(SN * pSn)
{
	UINT8  sn[8] 		= {0};
	UINT16 u16tmp		= 0;
	UINT16 i 			= 0;

	if ( NULL == pSn )
	{
	    DEBUGMSG(1,("Level:%d [GetSerialNum]pSn is NULL \n", ERR));
		return V_FALSE;
	}
	if ( 0 != (u16tmp = OWReset()))
	{
		DEBUGMSG(1,("Level:%d [GetSerialNum]u16tmp is 0x%x\n \n", ERR, u16tmp));
	    return V_FALSE;
	}

	memset(sn, 0xFF, sizeof(sn));

	OWWriteByte(0x33);//启动读取过程

	for ( i = 0; i < 8; i++ )
	{	
	    sn[i] = OWReadByte();
	}

	if ( sn[7] != crc8(sn, 7))
	{
	    DEBUGMSG(1,("Level:%d [GetSerialNum]CRC error \n", ERR));
		return V_FALSE;
	}
	memcpy(pSn->SerialNum, sn, sizeof(sn));
	return V_TRUE;

}


UINT8 crc8(unsigned char *pDst,unsigned char length)
{
    unsigned char i,j,aa,check,flag;
    check=0;
    for (i=0;i<length;i++)
    {
        aa=*pDst++;
        for(j=0;j<8;j++)
        {
            flag=(check^aa)&1;
            check>>=1;
            if(flag){check^=0x0c;check|=0x80;}
            aa>>=1;
        }
    }
    return check;
}

BOOL CheckCopyRight(void)
{
	SN SnGet;
	UINT8 SnStord[8];
	UINT16 i = 0;
	memset(&SnGet, 0xFF, sizeof(SnGet));
	memset(SnStord, 0xFF, sizeof(SnStord));

	//获取2411的数据,由于2411读写时序不是很稳定,这里最多尝试20次
	for ( i = 0 ; i < 20 ; i++ )
	{
		if ( V_TRUE == GetSerialNum(&SnGet))
		{
			break;
		}
	}

	if ( i >= 20)
	{
		DEBUGMSG(1,("Level:%d [CheckCopyRight]GetSerialNum fail\n", ERR));
	    return V_FALSE;
	}

	//获取存储的SN数据
	if ( V_FALSE == EM85xxI2C__Read(SN_DEV_ADDR, SN_OFFSET, SnStord, sizeof(SnStord)))
	{
	    DEBUGMSG(1,("Level:%d [CheckCopyRight] objI2COp.ReadArray fail\n", ERR));
		return V_FALSE;
	}

	//如果不匹配,则认为是非法的
	if ( 0 != memcmp(SnGet.SerialNum, SnStord, sizeof(SnGet)) )	
	{
		DEBUGMSG(1,("Level:%d [CheckCopyRight] Illegal copy\n", FATAL));
		return V_FALSE;
	}

	return V_TRUE;
}



BOOL StoreSerialNum(void)
{
	SN SnGet;

	memset(&SnGet, 0xFF, sizeof(SnGet));

	if ( V_FALSE == GetSerialNum(&SnGet))
	{
		DEBUGMSG(1,("Level:%d [StoreSerialNum]GetSerialNum fail\n", ERR));
	    return V_FALSE;
	}

	if ( V_FALSE == EM85xxI2C__Write(SN_DEV_ADDR, SN_OFFSET, SnGet.SerialNum, sizeof(SnGet)))
	{
		DEBUGMSG(1,("Level:%d [StoreSerialNum] objI2COp.WriteArray fail\n", ERR));
		return V_FALSE;
	}
	return V_TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -