//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{ 
  unsigned char error=0;
  unsigned int i;

  s_transstart();                   //transmission start
	

	
	//发送测量命令
  switch(mode){                     //send command to sensor
    case TEMP	: error+=s_write_byte(MEASURE_TEMP); break;
    case HUMI	: error+=s_write_byte(MEASURE_HUMI); break;
    default     : break;	 
  }

	//读数

  for (i=0;i<60000;i++)   
		if(SDA_READ()==0) break; //wait until sensor has finished the measurement
  if(SDA_READ()) error+=1;               // or timeout (~2 sec.) is reached
  *(p_value+1)  =s_read_byte(ACK);    //read the first byte (MSB)
 // printf("p_value is %x",*p_value);
  *(p_value)=s_read_byte(ACK);
 // printf("p_value+1 is %x",*(p_value+1));    //read the second byte (LSB)
  *p_checksum =s_read_byte(noACK);  //read checksum
	
  return error;
//  }
}
Example #2
0
uint8_t ICACHE_FLASH_ATTR 
twi_readFrom(uint8_t address, uint8_t *buf, unsigned int len,
	     uint8_t sendStop)
{
	unsigned int i;
	if (!twi_write_start()) {
		serial_print("I2C: bus busy\r\n");
		return 4;
	}
	if (!twi_write_byte(((address << 1) | 1) & 0xFF)) {
		if (sendStop)
			twi_write_stop();
		serial_print("I2C: received NACK on transmit of address\r\n");
		return 2;
	}
	for (i = 0; i < (len - 1); i++)
		buf[i] = twi_read_byte(false);
	buf[len - 1] = twi_read_byte(true);
	if (sendStop)
		twi_write_stop();
	i = 0;
	while (SDA_READ() == 0 && (i++) < 10) {
		SCL_LOW();
		twi_delay(twi_dcount);
		SCL_HIGH();
		twi_delay(twi_dcount);
	}
	return 0;
}
Example #3
0
uint8_t ICACHE_FLASH_ATTR 
twi_writeTo(uint8_t address, uint8_t *buf, unsigned int len,
	    uint8_t sendStop)
{
	unsigned int i;
	if (!twi_write_start()) {
		serial_print("I2C: bus busy\r\n");
		return 4;
	}
	if (!twi_write_byte(((address << 1) | 0) & 0xFF)) {
		if (sendStop)
			twi_write_stop();
		serial_print("I2C: received NACK on transmit of address\r\n");
		return 2;
	}
	for (i = 0; i < len; i++) {
		if (!twi_write_byte(buf[i])) {
			if (sendStop)
				twi_write_stop();
			serial_print("I2C: received NACK on transmit of data\r\n");
			return 3;
		}
	}
	if (sendStop)
		twi_write_stop();
	i = 0;
	while (SDA_READ() == 0 && (i++) < 10) {
		SCL_LOW();
		twi_delay(twi_dcount);
		SCL_HIGH();
		twi_delay(twi_dcount);
	}
	return 0;
}
Example #4
0
uint8_t twi_status() {
    if (SCL_READ() == 0)
      return I2C_SCL_HELD_LOW; // SCL held low by another device, no procedure available to recover

    int clockCount = 20;
    while (SDA_READ() == 0 && clockCount-- > 0) { // if SDA low, read the bits slaves have to sent to a max
        twi_read_bit();
        if (SCL_READ() == 0) {
          return I2C_SCL_HELD_LOW_AFTER_READ; // I2C bus error. SCL held low beyond slave clock stretch time
        }
    }
    if (SDA_READ() == 0)
      return I2C_SDA_HELD_LOW; // I2C bus error. SDA line held low by slave/another_master after n bits.
    
    if (!twi_write_start())
      return I2C_SDA_HELD_LOW_AFTER_INIT;  // line busy. SDA again held low by another device. 2nd master?

    return I2C_OK;
}
Example #5
0
static bool twi_read_bit(void) {
  uint32_t i = 0;
  SCL_LOW();
  SDA_HIGH();
  twi_delay(twi_dcount+2);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  bool bit = SDA_READ();
  twi_delay(twi_dcount);
  return bit;
}
Example #6
0
static bool twi_write_start(void) {
  SCL_HIGH();
  SDA_HIGH();
  if (SDA_READ() == 0) {
    return false;
  }
  twi_delay(twi_dcount);
  SDA_LOW();
  twi_delay(twi_dcount);
  return true;
}
Example #7
0
static bool ICACHE_FLASH_ATTR twi_read_bit()
{
	unsigned int i = 0;
	SCL_LOW();
	SDA_HIGH();
	twi_delay(twi_dcount + 2);
	SCL_HIGH();
	while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);	// Clock stretching
	bool bit = SDA_READ();
	twi_delay(twi_dcount);
	return bit;
}
Example #8
0
static bool ICACHE_FLASH_ATTR twi_write_start(void)
{
	SCL_HIGH();
	SDA_HIGH();
	if (SDA_READ() == 0) {
		serial_printf("twi write start sda read false\r\n");
		return false;
	}
	twi_delay(twi_dcount);
	SDA_LOW();
	twi_delay(twi_dcount);
	return true;
}
Example #9
0
unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop){
  unsigned int i;
  if(!twi_write_start()) return 4;//line busy
  if(!twi_write_byte(((address << 1) | 1) & 0xFF)) {
    if (sendStop) twi_write_stop();
    return 2;//received NACK on transmit of address
  }
  for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false);
  buf[len-1] = twi_read_byte(true);
  if(sendStop) twi_write_stop();
  i = 0;
  while(SDA_READ() == 0 && (i++) < 10){
    SCL_LOW();
    twi_delay(twi_dcount);
    SCL_HIGH();
    unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
    twi_delay(twi_dcount);
  }
  return 0;
}
//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
{ 
  unsigned char i,val=0;
  SDA_OUT(1);                           //release DATA-line
  for (i=0x80;i>0;i=i>>1)             //shift bit for masking
  { 
    SCL_OUT(1);                        //clk for SENSI-BUS
    if (SDA_READ()) val=(val | i);        //read bit  
    SCL_OUT(0);  					 
  }
  SDA_OUT(!ack);                        //in case of "ack==1" pull down DATA-Line
  delay_us(2);                          //observe setup time
  SCL_OUT(1);                            //clk #9 for ack
  delay_us(6);          //pulswith approx. 5 us 
  SCL_OUT(0);
  delay_us(2);                         //observe hold time						    
  SDA_OUT(1);                          //release DATA-line
  return val;
}
Example #11
0
bool i2c_write(alt_u32 clk_base, alt_u32 data_base, alt_u8 Data){ // return true if device response ack
    alt_u8 Mask = 0x80;
    bool bAck;
    int i;
    
    // assume, SCL = 0
    
    SDA_DIR_OUT(data_base);  // data write mode
    
    for(i=0;i<8;i++){
        SCL_LOW(clk_base);  // new, make sure data change at clk low
        // output data on bus
        if (Data & Mask){ // there is a delay in this command
            SDA_HIGH(data_base);
        }else{    
            SDA_LOW(data_base);
        }
        Mask >>= 1; // there is a delay in this command
        // clock high
        SCL_HIGH(clk_base);
        SCL_DELAY;
        SCL_LOW(clk_base);
        SCL_DELAY;
    }
    
    //===== get ack
    SDA_DIR_IN(data_base);  // data read mode
    //SCL_DELAY;
    // clock high
    SCL_HIGH(clk_base);  // clock high
    SCL_DELAY;  // clock high delay
    bAck = SDA_READ(data_base)?FALSE:TRUE;  // get ack
    //SCL_DELAY;
    //SDA_DIR_OUT;
    SCL_LOW(clk_base); // clock low         
    SCL_DELAY; // clock low delay
    return bAck;
}    
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge 
{ 
  unsigned char i,error=0;  
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { 
  	if (i & value)
    SDA_OUT(1);          //masking value with i , write to SENSI-BUS
    else SDA_OUT(0);                        
    delay_us(2);                      //observe setup time
    SCL_OUT(1);                          //clk for SENSI-BUS
    delay_us(6);        //pulswith approx. 5 us  	
    SCL_OUT(0);
    delay_us(2);                         //observe hold time
  }
  SDA_OUT(1);                          //release DATA-line
  delay_us(2);                         //observe setup time
  SCL_OUT(1);                          //clk #9 for ack 
  error=SDA_READ();                      //check ack (DATA will be pulled down by SHT11)
  SCL_OUT(0);       
  return error;                     //error=1 in case of no acknowledge
}
Example #13
0
void i2c_read(alt_u32 clk_base, alt_u32 data_base, alt_u8 *pData, bool bAck){ // return true if device response ack
    alt_u8 Data=0;
    int i;
    
    // assume SCL = low
    
    SDA_DIR_IN(data_base);  // set data read mode
    SCL_LOW(clk_base); // clock low
    SCL_DELAY; // clock low delay

    for(i=0;i<8;i++){
        Data <<= 1;
        SCL_HIGH(clk_base);  // clock high
        SCL_DELAY;
        if (SDA_READ(data_base))  // read data   
            Data |= 0x01;
        SCL_LOW(clk_base);  // clock log  
        SCL_DELAY;
    }
    
    // send ACK
    SCL_LOW(clk_base);  // new, make sure data change at clk low
    SDA_DIR_OUT(data_base);  // set data write mode
    if (bAck)
        SDA_LOW(data_base);
    else
        SDA_HIGH(data_base);
    SCL_HIGH(clk_base); // clock high
    SCL_DELAY; // clock high  delay
    SCL_LOW(clk_base); // clock low
    SCL_DELAY; // clock low delay
    SDA_LOW(data_base);  // data low
    SCL_DELAY; // data low delay
//    SDA_DIR_IN;  // set data read mode
    
    *pData = Data;
}
Example #14
0
unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){
  unsigned int i;
  if(!twi_write_start()) return 4;//line busy
  if(!twi_write_byte(((address << 1) | 0) & 0xFF)) {
    if (sendStop) twi_write_stop();
    return 2; //received NACK on transmit of address
  }
  for(i=0; i<len; i++) {
    if(!twi_write_byte(buf[i])) {
      if (sendStop) twi_write_stop();
      return 3;//received NACK on transmit of data
    }
  }
  if(sendStop) twi_write_stop();
  i = 0;
  while(SDA_READ() == 0 && (i++) < 10){
    SCL_LOW();
    twi_delay(twi_dcount);
    SCL_HIGH();
    unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit
    twi_delay(twi_dcount);
  }
  return 0;
}
Example #15
0
void ICACHE_RAM_ATTR onSdaChange(void)
{
	static uint8_t sda;
	static uint8_t scl;
	sda	= SDA_READ();
	scl = SCL_READ();

	switch (twip_state)
	{
		case TWIP_IDLE:
			if (!scl) {
				// DATA - ignore
			} else if (sda) {
				// STOP - ignore
			} else {
				// START
				bitCount = 8;
				twip_state = TWIP_START;
				ets_timer_arm_new(&timer, twi_timeout_ms, false, true); // Once, ms
			}
			break;

		case TWIP_START:
		case TWIP_REP_START:
		case TWIP_SEND_ACK:
		case TWIP_WAIT_ACK:
		case TWIP_SLA_R:
		case TWIP_REC_ACK:
		case TWIP_READ_ACK:
		case TWIP_RWAIT_ACK:
		case TWIP_WRITE:
			if (!scl) {
				// DATA - ignore
			} else {
				// START or STOP
				SDA_HIGH();	 // Should not be necessary
				twip_status = TW_BUS_ERROR;
				twi_onTwipEvent(twip_status);
				twip_mode = TWIPM_WAIT;
				twip_state = TWIP_BUS_ERR;
			}
			break;

		case TWIP_WAIT_STOP:
		case TWIP_BUS_ERR:
			if (!scl) {
				// DATA - ignore
			} else {
				if (sda) {
					// STOP
					SCL_LOW();	// clock stretching
					ets_timer_disarm(&timer);
					twip_state = TWIP_IDLE;
					twip_mode = TWIPM_IDLE;
					SCL_HIGH();
				} else {
					// START
					if (twip_state == TWIP_BUS_ERR) {
						// ignore
					} else {
						bitCount = 8;
						twip_state = TWIP_REP_START;
						ets_timer_arm_new(&timer, twi_timeout_ms, false, true); // Once, ms
					}
				}
			}
			break;

		case TWIP_SLA_W:
		case TWIP_READ:
			if (!scl) {
				// DATA - ignore
			} else {
				// START or STOP
				if (bitCount != 7) {
					// inside byte transfer - error
					twip_status = TW_BUS_ERROR;
					twi_onTwipEvent(twip_status);
					twip_mode = TWIPM_WAIT;
					twip_state = TWIP_BUS_ERR;
				} else {
					// during first bit in byte transfer - ok
					SCL_LOW();	// clock stretching
					twip_status = TW_SR_STOP;
					twi_onTwipEvent(twip_status);
					if (sda) {
						// STOP
						ets_timer_disarm(&timer);
						twip_state = TWIP_IDLE;
						twip_mode = TWIPM_IDLE;
					} else {
						// START
						bitCount = 8;
						ets_timer_arm_new(&timer, twi_timeout_ms, false, true); // Once, ms
						twip_state = TWIP_REP_START;
						twip_mode = TWIPM_IDLE;
					}
				}
			}
			break;

		default:
			break;
	}
}
Example #16
0
void ICACHE_RAM_ATTR onSclChange(void)
{
	static uint8_t sda;
	static uint8_t scl;

	sda	= SDA_READ();
	scl = SCL_READ();

	twip_status = 0xF8;		// reset TWI status

	switch (twip_state)
	{
		case TWIP_IDLE:
		case TWIP_WAIT_STOP:
		case TWIP_BUS_ERR:
			// ignore
			break;

		case TWIP_START:
		case TWIP_REP_START:
		case TWIP_SLA_W:
		case TWIP_READ:
			if (!scl) {
				// ignore
			} else {
				bitCount--;
				twi_data <<= 1;
				twi_data |= sda;

				if (bitCount != 0) {
					// continue
				} else {
					twip_state = TWIP_SEND_ACK;
				}
			}
			break;

		case TWIP_SEND_ACK:
			if (scl) {
				// ignore
			} else {
				if (twip_mode == TWIPM_IDLE) {
					if ((twi_data & 0xFE) != twi_addr) {
						// ignore
					} else {
						SDA_LOW();
					}
				} else {
					if (!twi_ack) {
						// ignore
					} else {
						SDA_LOW();
					}
				}
				twip_state = TWIP_WAIT_ACK;
			}
			break;

		case TWIP_WAIT_ACK:
			if (scl) {
				// ignore
			} else {
				if (twip_mode == TWIPM_IDLE) {
					if ((twi_data & 0xFE) != twi_addr) {
						SDA_HIGH();
						twip_state = TWIP_WAIT_STOP;
					} else {
						SCL_LOW();	// clock stretching
						SDA_HIGH();
						twip_mode = TWIPM_ADDRESSED;
						if (!(twi_data & 0x01)) {
							twip_status = TW_SR_SLA_ACK;
							twi_onTwipEvent(twip_status);
							bitCount = 8;
							twip_state = TWIP_SLA_W;
						} else {
							twip_status = TW_ST_SLA_ACK;
							twi_onTwipEvent(twip_status);
							twip_state = TWIP_SLA_R;
						}
					}
				} else {
					SCL_LOW();	// clock stretching
					SDA_HIGH();
					if (!twi_ack) {
						twip_status = TW_SR_DATA_NACK;
						twi_onTwipEvent(twip_status);
						twip_mode = TWIPM_WAIT;
						twip_state = TWIP_WAIT_STOP;
					} else {
						twip_status = TW_SR_DATA_ACK;
						twi_onTwipEvent(twip_status);
						bitCount = 8;
						twip_state = TWIP_READ;
					}
				}
			}
			break;

		case TWIP_SLA_R:
		case TWIP_WRITE:
			if (scl) {
				// ignore
			} else {
				bitCount--;
				(twi_data & 0x80) ? SDA_HIGH() : SDA_LOW();
				twi_data <<= 1;

				if (bitCount != 0) {
					// continue
				} else {
					twip_state = TWIP_REC_ACK;
				}
			}
			break;

		case TWIP_REC_ACK:
			if (scl) {
				// ignore
			} else {
				SDA_HIGH();
				twip_state = TWIP_READ_ACK;
			}
			break;

		case TWIP_READ_ACK:
			if (!scl) {
				// ignore
			} else {
				twi_ack_rec = !sda;
				twip_state = TWIP_RWAIT_ACK;
			}
			break;

		case TWIP_RWAIT_ACK:
			if (scl) {
				// ignore
			} else {
				SCL_LOW();	// clock stretching
				if (twi_ack && twi_ack_rec) {
					twip_status = TW_ST_DATA_ACK;
					twi_onTwipEvent(twip_status);
					twip_state = TWIP_WRITE;
				} else {
					// we have no more data to send and/or the master doesn't want anymore
					twip_status = twi_ack_rec ? TW_ST_LAST_DATA : TW_ST_DATA_NACK;
					twi_onTwipEvent(twip_status);
					twip_mode = TWIPM_WAIT;
					twip_state = TWIP_WAIT_STOP;
				}
			}
			break;

		default:
			break;
	}
}