📄 ds2411.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 + -