GX28E17兼容DS28E17 一种1-Wire从机至I2C主机桥接器的二氧化碳(CO2)模组应用

GX28E17兼容DS28E17 一种1-Wire从机至I2C主机桥接器的二氧化碳(CO2)模组应用

一、文章摘要

二、基本参数

三、器件应用

四、参考驱动

一、文章摘要

        CO2浓度监测模组应用有长远距离要求,在标准模式下,I2C通信距离长度被限制在几米,已无法满足需求。本文主要介绍使用GX28E17延长I2C器件通信距离,同时降低成本。

        I2C总线的最大距离取决于电容大小。因为构建系统必须以容纳400pF的最大总线电容,以满足I2C总线规范(2014年4月6日至4日修订)中列出的上升时间要求。为了通过运行在最大允许总线电容之上实现更大的距离,I2C总线规范允许以较低的速度运行,使用更高的驱动输出设备,将总线分成带有总线缓冲区的段,或使用开关上拉电路。虽然从表面上看,这些方法似乎可行,但它们要么不满足长距离要求,要么显著增加成本。因此使用GX28E17 1-Wire对I2C主桥接器。

二、基本参数

●● 产品特点

        ● 将1-Wire 通信协议转换为 I2C 主I/O

        ● 通过单触点、1-Wire 接口操作 I2C 从设备外设

        ● 使用1-Wire 协议扩展 I2C 通信距离(典型100米

        ● 灵活的1-Wire 从机和 I2C 主机工作模式

        ● 1-Wire接口支持 15kbps 和 77kbps 通信速率,带分组 I2C 数据有效负载

        ● I2C 的标准 100kHz 、400kHz 和1MHZ 通信速率

        ● I2C接口支持时钟延展功能

        ● 工厂编程的唯一 64 位 1-Wire ROM ID 为终端设备提供不可更改的序列号

●● 低功耗

        ● 正常工作时为 1.5mA(典型值)

         ● 睡眠模式下为 0.3μA(典型值)

         ● 具有可用于睡眠和唤醒灵活性的独立引脚

         ● 可由唤醒引脚控制的远程电源

         ● 通过睡眠引脚或 1-Wire 器件命令使能睡眠模式

●● 应用场景

        ● 远端外设识别与控制

        ● IIC传感器

        ● 显示控制器

        ● 数模、模数转换器

三、器件应用

一、典型应用电路

二、1-Wire 信号时序

        1-Wire 协议在单根信号线上定义了以下六种基本信号类型:复位脉冲,响应脉冲,写 0,写 1,读 0, 读 1。除响应脉冲外,所有信号都由主机启动,且以总线下降沿为计时起点。

         如图 1 所示主机通过拉低总线超过 480us 向总线发送复位脉冲。GX28E17识别到复位脉冲后会复位自身通信状态,并在复位脉冲结束后(主机释放总线) 等待一定时间(15~60us)再发送响应脉冲(通过拉低总线 60~240us)。为了检测响应脉冲,主机必须在特定窗口时间内对总线采样。当采样到总线为低电平时, 说明存在响应脉冲,表示GX28E17已经准备好开始通信;当采样到总线为高电平时,说明不存在响应脉冲,表示复位脉冲未被GX28E17识别,或总线上未挂载任何器件。

        1-Wire 数据传输以时隙(Time Slot)为基本单位,每次仅携带一位数据。 其中,写时隙将主机发送的数据传输给IIC器件;读时隙将GX28E17发送的数 据传输给主机。 读写时隙均开始于主机拉低总线,时隙宽度不短于 65us,相邻时隙之间必 须提供不短于 1us 的恢复时间。 写时隙启动后,GX28E17将在特定窗口时间内对总线采样,如图 2 所示。 采样结果即为GX28E17接收到的一位数据。

        ● 写 1 时隙:主机拉低总线后,必须在 15us 内释放总线;

        ● 写 0 时隙:主机拉低总线后,必须维持至少 60us 才能释放总线。

        当且仅当主机启动读时隙时,GX28E17才能向主机发送数据。如图 3 所示, 主机拉低总线启动读时隙后,必须维持 1~15us 以确保总线下降沿能够被GX28E17 识别。如果GX28E17 识别成功,将根据自身即将发送的数据来决定对总线的后续操作。因此,读时隙可以进一步区分为以下两种信号:

         ● 读 1 时隙:从总线下降沿开始,直接释放总线;

         ● 读 0 时隙:从总线下降沿开始,拉低总线并维持 15~60us。

        为了接收 GX28E17发送的数据,主机必须在特定窗口时间内对总线采样, 采样结果即为所接收到的一位数据。注意:读 0 时隙的数据有效时间最短为 15us, 因此采样窗口最大不能超过该有效时间。出于最大化时序裕度的考虑,建议将主 机释放总线时间尽可能提前,将主机采样时间尽可能延后。

三、1-Wire 通信流程

        GX28E17 的 1-Wire 通信流程由初始化序列、寻址命令、功能命令和 I2C 数据这四个部分组成。当初始化完成后主机可以发送寻址命令来搜索和选择特定器件。GX28E17 支持七种寻址命令

● 读寻址(Read ROM)[33h]

● 匹配寻址(Match ROM)[55h]

● 搜索寻址(Search ROM)[F0h]

● 跳过寻址(Skip ROM)[CCh]

● 恢复寻址(Resume ROM)[A5h]

● 超速跳过寻址(Overdrive-Skip ROM)[3Ch]

● 超速匹配寻址(Overdrive-Match ROM)[69h]

四、二氧化碳模组GX28E17应用
4.1 产品外观

4.2产品功能特点

4.3产品指标参数

4.4寄存器命令
4.5.1写寄存器

4.5.2读数据

4.5.3寄存器数据表

4.6部分寄存器说明
4.6.1开始测量

4.6.2读取测量

4.6.3停止测量

4.7实测波形
4.7.1 读寻址

4.7.2 发送命令 0XE4B8 读取数据就绪状态

4.7.3 发送 CO2 读值命令

4.7.4 CO2 读值返回

四、GX28E17驱动参考(部分)

gx28e17.c

#include "globle.h"

/*---------------------------------------------------------------------
  Function    : gx28e17_read_rom             
  Description : execute READ_ROM command
  Parameter 1 : 1-wire communication speed
  Return      : ID number of current device (0=no device was found)
---------------------------------------------------------------------*/
uint64_t gx28e17_read_rom(u8 spd)
{
  u8  rxd = 0;
  uint64_t id  = 0;
  u8 i;
	
  if(onewire_reset(spd) == ACK) {
		onewire_write(spd, ROM_READ);
    for(  i = 0; i < 8; i ++) {
      rxd = onewire_read(spd);
			printf("%02X",rxd);
      id  = id | (((uint64_t) rxd) << (8 * i));
    }
  }
  else
    printf("Read ROM : No device on the bus.\r\n");
  
  return id;
}

 
/*---------------------------------------------------------------------
  Function    : gx28e17_match_rom             
  Description : execute MATCH_ROM command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : ID number of selected device
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_match_rom(u8 spd, uint64_t id)
{
  u8 txd = 0;
  u8 i;
	
  if(onewire_reset(spd) == ACK) {
    onewire_write(spd, ROM_MATCH);
    for(  i = 0; i < 8; i ++) {
      txd = (u8) (id >> (8 * i));
      onewire_write(spd, txd);
    }
    return DONE;
  }
  else {
    printf("Match ROM : No device on the bus.\r\n");
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_match_rom_od             
  Description : execute MATCH_ROM_OVERDRIVE command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : ID number of selected device
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_match_rom_od(u8 spd, uint64_t id)
{
  u8 txd = 0;
  u8 i;
	
  if(onewire_reset(spd) == ACK) {
    onewire_write(spd, ROM_MATCH_OD);
    for(  i = 0; i < 8; i ++) {
      txd = (u8) (id >> (8 * i));
      onewire_write(SPD_OD, txd);
    }
    return DONE;
  }
  else {
    printf("Match ROM (od) : No device on the bus.\r\n");
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_search_rom             
  Description : execute search algorithm
  Parameter 1 : 1-wire communication speed
  Parameter 2 : ID number array of devices found
  Return      : number of devices found (0=no device was found)
---------------------------------------------------------------------*/
u8 gx28e17_search_rom(u8 spd, uint64_t * ids)
{
  u8  num     = 0;   // number of device found
  u8  pos     = 0;   // current bit position
  u8  dir     = 0;   // search direction
  u8  val     = 0;   // current bit
  u8  val_cmp = 0;   // complement of current bit
  u8  brn_new = 0;   // the bit position where a new branch is taken
  u8  brn_chk = 0;   // branch checkpoint
  uint64_t cur_id  = 0;   // current ID
  uint64_t reg_id  = 0;   // last ID found
  
  do {
    if(onewire_reset(spd) == ACK) {
      brn_new = 0;
      cur_id  = 0;
      onewire_write(spd, ROM_SEARCH);
      for(pos = 1; pos < 65; pos ++) {
        cur_id  = cur_id >> 1;
        val     = onewire_read_bit(spd);
        val_cmp = onewire_read_bit(spd);
        /*
          00 : There are both 0s and 1s in the current bit position of the participating ROM numbers => discrepancy
          01 : There are only 0s        in the current bit position of the participating ROM numbers
          10 : There are only 1s        in the current bit position of the participating ROM numbers
          11 : No device participating in the search (atypical situation)
        */
        if((val == 0) && (val_cmp == 0)) {
          /*
            pos < brn_chk : take the same path as last time (from last ROM number found)
            pos = brn_chk : take the  "1" path
            pos > brn_chk : take the  "0" path
          */
          if(pos < brn_chk)
            dir = ((u8) (reg_id >> (pos - 1))) & 0x01;
          else if(pos == brn_chk)
            dir = 1;
          else
            dir = 0;
          
          if(dir == 0)
            brn_new = pos;
        }
        else if((val == 0) && (val_cmp != 0))
          dir = 0;
        else if((val != 0) && (val_cmp == 0))
          dir = 1;
        else {
							printf("Search ROM : The device discovered is removed from the 1-wire bus during the search. (bit %d)\r\n", pos);
							return 0;
						}
        cur_id = cur_id | ((dir == 0) ? 0x0000000000000000 : 0x8000000000000000);
        onewire_write_bit(spd, dir);
      }
      brn_chk  = brn_new;
      reg_id   = cur_id;
      ids[num] = cur_id;
      num ++;
    }
    else {
      printf("Search ROM : No device on the bus.\r\n");
      return 0;
    }
  } while (brn_chk > 0);
  
  return num; // Returning zero means that no device was found
}

/*---------------------------------------------------------------------
  Function    : gx28e17_skip_rom             
  Description : execute SKIP_ROM command
  Parameter 1 : 1-wire communication speed
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_skip_rom(u8 spd)
{
  if(onewire_reset(spd) == ACK) {
    onewire_write(spd, ROM_SKIP);
    return DONE;
  }
  else {
    printf("Skip ROM : No device on the bus.\r\n");
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_skip_rom_od             
  Description : execute SKIP_ROM_OVERDRIVE command
  Parameter 1 : 1-wire communication speed
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_skip_rom_od(u8 spd)
{
  if(onewire_reset(spd) == ACK) {
    onewire_write(spd, ROM_SKIP_OD);
    return DONE;
  }
  else {
    printf("Skip ROM (od) : No device on the bus.\r\n");
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_resume_rom             
  Description : execute RESUME_ROM command
  Parameter 1 : 1-wire communication speed
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_resume_rom(u8 spd)
{
  if(onewire_reset(spd) == ACK) {
    onewire_write(spd, ROM_RESUME);
    return DONE;
  }
  else {
    printf("Resume ROM : No device on the bus.\r\n");
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_with_stop             
  Description : execute WRITE_DATA_WITH_STOP command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C slave address
  Parameter 3 : I2C write length
  Parameter 4 : I2C write data array
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_write_with_stop(u8 spd, u8 addr, u8 wlen, u8 * wdat)
{
	u8  st  = 0;
  u8  wst = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_WR_STP);
  onewire_write(spd, addr);
  onewire_write(spd, wlen);
  for(  i = 0; i < wlen; i ++)
    onewire_write(spd, wdat[i]);
  
  // crc
  crc = gx28e17_generate_crc(DEV_WR_STP, addr, wlen, wdat, 0);
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
  
  // poll
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Write with stop : Exceed query limit.\r\n");
			return ERROR;
    }
  }
  
  // read return bytes
  st  = onewire_read(spd);
  wst = onewire_read(spd);
  switch(st) {
    case ERR_STA : {
      printf("Write with stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {
      printf("Write with stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {
      printf("Write with stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
  if(wst == 0)
    return DONE;  // Done correctly
  else {
    printf("Write with stop : Byte %d is not acknowledged by the I2C slave device.\r\n", wst);
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_no_stop             
  Description : execute WRITE_DATA_NO_STOP command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C slave address
  Parameter 3 : I2C write length
  Parameter 4 : I2C write data array
  Return      : finish flag
---------------------------------------------------------------------*/
//
u8 gx28e17_write_no_stop(u8 spd, u8 addr, u8 wlen, u8 * wdat)
{
  u8  st  = 0;
  u8  wst = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_WR);//命令0x5A  --》Write data no stop
  onewire_write(spd, addr);//地址
  onewire_write(spd, wlen);//长度
  for(  i = 0; i < wlen; i ++)//0x02
    onewire_write(spd, wdat[i]);
  
  // crc
  crc = gx28e17_generate_crc(DEV_WR, addr, wlen, wdat, 0);
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
  
  // poll---》这里实现方式有三种:主机等待一个预定的时间,检测BUSY pin的状态,读取非0
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Write no stop : Exceed query limit.\r\n");
			return 0;
    }
  }
  
  // read return bytes
  st  = onewire_read(spd);
  wst = onewire_read(spd);
  switch(st) {
    case ERR_STA : {//0x08
      printf("Write no stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {//0x02
      printf("Write no stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {//0x01
      printf("Write no stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
  if(wst == 0)
    return DONE;  // Done correctly
  else {
    printf("Write no stop : Byte %d = %02X is not acknowledged by the I2C slave device.\r\n", wst,wst);
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_only_no_stop             
  Description : execute WRITE_DATA_ONLY command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C write length
  Parameter 3 : I2C write data array
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_write_only_no_stop(u8 spd, u8 wlen, u8 * wdat)
{
  u8  st  = 0;
  u8  wst = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_WR_OLY);
  onewire_write(spd, wlen);
  for( i = 0; i < wlen; i ++)
    onewire_write(spd, wdat[i]);
  
  // crc
  crc = gx28e17_generate_crc(DEV_WR_OLY, 0, wlen, wdat, 0);
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
  
  // poll
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Write only no stop : Exceed query limit.\r\n");
			return ERROR;
    }
  }
  
  // read return bytes
  st  = onewire_read(spd);
  wst = onewire_read(spd);
  switch(st) {
    case ERR_STA : {
      printf("Write only no stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {
      printf("Write only no stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {
      printf("Write only no stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
  if(wst == 0)
    return DONE;  // Done correctly
  else {
    printf("Write only no stop : Byte %d is not acknowledged by the I2C slave device.\r\n", wst);
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_only_with_stop             
  Description : execute WRITE_DATA_ONLY_WITH_STOP command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C write length
  Parameter 3 : I2C write data array
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_write_only_with_stop(u8 spd, u8 wlen, u8 * wdat)
{
  u8  st  = 0;
  u8  wst = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i ;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_WR_OLY_STP);
  onewire_write(spd, wlen);
  for(  i = 0; i < wlen; i ++)
    onewire_write(spd, wdat[i]);
  
  // crc
  crc = gx28e17_generate_crc(DEV_WR_OLY_STP, 0, wlen, wdat, 0);
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
  
  // poll
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Write only with stop : Exceed query limit.\r\n");
			return ERROR;
    }
  }
  
  // read return bytes
  st  = onewire_read(spd);
  wst = onewire_read(spd);
  switch(st) {
    case ERR_STA : {
      printf("Write only with stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {
      printf("Write only with stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {
      printf("Write only with stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
  if(wst == 0)
    return DONE;  // Done correctly
  else {
    printf("Write only with stop : Byte %d is not acknowledged by the I2C slave device.\r\n", wst);
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_read_with_stop             
  Description : execute READ_DATA_WITH_STOP command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C slave address
  Parameter 3 : I2C read length
  Parameter 4 : I2C read data array
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_read_with_stop(u8 spd, u8 addr, u8 rlen, u8 * rdat)
{
  u8  st  = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_RD_STP);
  onewire_write(spd, addr);
  onewire_write(spd, rlen);
  
  // crc
  crc = gx28e17_generate_crc(DEV_RD_STP, addr, 0, 0, rlen);//读数据的CRC16
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
	
  // poll
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Read with stop : Exceed query limit.\r\n");
			return ERROR;
    }
  }
	
  // read return bytes
  st  = onewire_read(spd);
  switch(st) {
    case ERR_STA : {
      printf("Read with stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {
      printf("Read with stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {
      printf("Read with stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
	
	for(  i = 0; i < rlen; i ++)
    rdat[i] = onewire_read(spd);
  return DONE;  // Done correctly
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_read_with_stop             
  Description : execute WRITE_READ_DATA_WITH_STOP command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : I2C slave address
  Parameter 3 : I2C write length
  Parameter 4 : I2C write data array
  Parameter 5 : I2C read length
  Parameter 6 : I2C read data array
  Return      : finish flag
---------------------------------------------------------------------*/
u8 gx28e17_write_read_with_stop(u8 spd, u8 addr, u8 wlen, u8 * wdat, u8 rlen, u8 * rdat)
{
  u8  st  = 0;
  u8  wst = 0;
	u8  cnt = 0;
  uint16_t crc = 0;
  u8 i;
	
  // transmit 1-wire packet
  onewire_write(spd, DEV_WR_RD_STP);
  onewire_write(spd, addr);
  onewire_write(spd, wlen);
  for(  i = 0; i < wlen; i ++)
    onewire_write(spd, wdat[i]);
  onewire_write(spd, rlen);
  
  // crc
  crc = gx28e17_generate_crc(DEV_WR_RD_STP, addr, wlen, wdat, rlen);
  onewire_write(spd, ((u8)  crc));
  onewire_write(spd, ((u8) (crc >> 8)));
  
  // poll
  while(onewire_read_bit(spd) != 0) {
    delay_100us();
		cnt ++;
		if(cnt > POLL_MAX) {
			printf("Write read with stop : Exceed query limit.\r\n");
			return ERROR;
    }
  }
  
  // read return bytes
  st  = onewire_read(spd);
  wst = onewire_read(spd);
  switch(st) {
    case ERR_STA : {
      printf("Write read with stop : Invalid start condition.\r\n");
      return ERROR;
    }
    
    case ERR_ADR : {
      printf("Write read with stop : I2C slave device does not acknowledge the I2C address.\r\n");
      return ERROR;
    }
    
    case ERR_CRC : {
      printf("Write read with stop : 1-Wire packet data does not match the corresponding CRC-16.\r\n");
      return ERROR;
    }
    
    default : break;
  }
  if(wst == 0) {
    for(  i = 0; i < rlen; i ++)
      rdat[i] = onewire_read(spd);
    return DONE;  // Done correctly
  }
  else {
    printf("Write read with stop : Byte %d is not acknowledged by the I2C slave device.\r\n", wst);
    return ERROR;
  }
}

/*---------------------------------------------------------------------
  Function    : gx28e17_write_config             
  Description : execute WRITE_CONFIGURATION command
  Parameter 1 : 1-wire communication speed
  Parameter 2 : configuration byte
  Return      : none
---------------------------------------------------------------------*/
void gx28e17_write_config(u8 spd, u8 cfg)
{
  onewire_write(spd, DEV_WR_CFG);
  onewire_write(spd, cfg);
}

/*---------------------------------------------------------------------
  Function    : gx28e17_read_config             
  Description : execute READ_CONFIGURATION command
  Parameter 1 : 1-wire communication speed
  Return      : configuration byte
---------------------------------------------------------------------*/
u8 gx28e17_read_config(u8 spd)
{
  u8 cfg = 0;
  
  onewire_write(spd, DEV_RD_CFG);
  cfg = onewire_read(spd);
  
  return cfg;
}

/*---------------------------------------------------------------------
  Function    : gx28e17_enable_sleep             
  Description : execute ENABLE_SLEEP_MODE command
  Parameter 1 : 1-wire communication speed
  Return      : none
---------------------------------------------------------------------*/
void gx28e17_enable_sleep(u8 spd)
{
  onewire_write(spd, DEV_EN_SLP);
}

/*---------------------------------------------------------------------
  Function    : gx28e17_read_revision             
  Description : execute READ_DEVICE_REVISION command
  Parameter 1 : 1-wire communication speed
  Return      : revision byte
---------------------------------------------------------------------*/
u8 gx28e17_read_revision(u8 spd)
{
  u8 rev = 0;
  
  onewire_write(spd, DEV_RD_REV);
  rev = onewire_read(spd);
  
  return rev;
}

/*---------------------------------------------------------------------
  Function    : gx28e17_generate_crc             
  Description : generate CRC-16 of 1-wire packet
  Parameter 1 : device command
  Parameter 2 : I2C slave address
  Parameter 3 : I2C write length
  Parameter 4 : I2C write data array
  Parameter 5 : I2C read length
  Return      : calculated CRC-16
---------------------------------------------------------------------*/
uint16_t gx28e17_generate_crc(u8 dcmd, u8 addr, u8 wlen, u8 * wdat, u8 rlen)
{
  u8  dat_in  = 0; // data input bit
  u8  crc_in  = 0; // crc  input bit
  uint16_t crc_reg = 0; // crc  register
  u8 i;
	u8 j;
	
  for(  i = 0; i < 8; i ++) {
    dat_in  = (dcmd >> i) & 0x01;
    crc_in  = ((u8) (crc_reg & 0x0001)) ^ dat_in;
    crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x0000);
  }
  
  if((dcmd == DEV_WR_STP) || (dcmd == DEV_WR) || (dcmd == DEV_WR_RD_STP) || (dcmd == DEV_RD_STP)) {
    for(  i = 0; i < 8; i ++) {
      dat_in  = (addr >> i) & 0x01;
      crc_in  = ((u8) (crc_reg & 0x0001)) ^ dat_in;
      crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x0000);
    }
  }
  
  if((dcmd == DEV_WR_STP) || (dcmd == DEV_WR) || (dcmd == DEV_WR_RD_STP) || (dcmd == DEV_WR_OLY) || (dcmd == DEV_WR_OLY_STP)) {
    for(  i = 0; i < 8; i ++) {
      dat_in  = (wlen >> i) & 0x01;
      crc_in  = ((u8) (crc_reg & 0x0001)) ^ dat_in;
      crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x0000);
    }
    for(  i = 0; i < wlen; i ++) {
      for(  j = 0; j < 8; j ++) {
        dat_in  = (wdat[i] >> j) & 0x01;
        crc_in  = ((u8) (crc_reg & 0x0001)) ^ dat_in;
        crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x0000);
      }
    }
  }
  
  if((dcmd == DEV_WR_RD_STP) || (dcmd == DEV_RD_STP)) {
    for(  i = 0; i < 8; i ++) {
      dat_in  = (rlen >> i) & 0x01;
      crc_in  = ((u8) (crc_reg & 0x0001)) ^ dat_in;
      crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x0000);
    }
  }
  
  return (~crc_reg);
}
GX28E17.h
#ifndef __GX28E17_HEADER_FILE
#define __GX28E17_HEADER_FILE

// library reference
#include "stdio.h"
#include "stdint.h"

// CRC-16 generator polynomial
#define CRC_POLY        0xA001

// I2C speed definition
#define SPD_SM          0x00
#define SPD_FM          0x01
#define SPD_PM          0x02

// max times of poll
#define POLL_MAX        50

// ROM command definition
#define ROM_READ        0x33
#define ROM_MATCH       0x55
#define ROM_SEARCH      0xF0
#define ROM_SKIP        0xCC
#define ROM_RESUME      0xA5
#define ROM_SKIP_OD     0x3C
#define ROM_MATCH_OD    0x69

// device command definition
#define DEV_WR_STP      0x4B
#define DEV_WR          0x5A
#define DEV_WR_OLY      0x69
#define DEV_WR_OLY_STP  0x78
#define DEV_RD_STP      0x87
#define DEV_WR_RD_STP   0x2D
#define DEV_WR_CFG      0xD2
#define DEV_RD_CFG      0xE1
#define DEV_EN_SLP      0x1E
#define DEV_RD_REV      0xC3

// finish flag
#define ERROR           0x00
#define DONE            0x01

// error definition
#define ERR_STA         0x08
#define ERR_ADR         0x02
#define ERR_CRC         0x01

// function declaration
uint64_t gx28e17_read_rom             (uint8_t spd);
uint8_t  gx28e17_match_rom            (uint8_t spd, uint64_t id);
uint8_t  gx28e17_match_rom_od         (uint8_t spd, uint64_t id);
uint8_t  gx28e17_search_rom           (uint8_t spd, uint64_t * ids);
uint8_t  gx28e17_skip_rom             (uint8_t spd);
uint8_t  gx28e17_skip_rom_od          (uint8_t spd);
uint8_t  gx28e17_resume_rom           (uint8_t spd);
uint8_t  gx28e17_write_with_stop      (uint8_t spd, uint8_t addr, uint8_t wlen, uint8_t * wdat);
uint8_t  gx28e17_write_no_stop        (uint8_t spd, uint8_t addr, uint8_t wlen, uint8_t * wdat);
uint8_t  gx28e17_write_only_no_stop   (uint8_t spd, uint8_t wlen, uint8_t * wdat);
uint8_t  gx28e17_write_only_with_stop (uint8_t spd, uint8_t wlen, uint8_t * wdat);
uint8_t  gx28e17_read_with_stop       (uint8_t spd, uint8_t addr, uint8_t rlen, uint8_t * rdat);
uint8_t  gx28e17_write_read_with_stop (uint8_t spd, uint8_t addr, uint8_t wlen, uint8_t * wdat, uint8_t rlen, uint8_t * rdat);
void     gx28e17_write_config         (uint8_t spd, uint8_t cfg);
uint8_t  gx28e17_read_config          (uint8_t spd);
void     gx28e17_enable_sleep         (uint8_t spd);
uint8_t  gx28e17_read_revision        (uint8_t spd);
uint16_t gx28e17_generate_crc         (uint8_t dcmd, uint8_t addr, uint8_t wlen, uint8_t * wdat, uint8_t rlen);


void Read_Rom(uint8_t spd);


#endif

友谊提示:

欢迎咨询交流GX28E17芯片应用,获取完整GX28E17驱动,联系方式如下:
TEL : 13128272535 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值