Пример #1
0
/*
 * Toggles out a single byte in master mode.
 *
 * Entry: SCL low, SDA any
 * Exit: SCL low, SDA high
 */
static int TwPut(uint8_t octet)
{
    int i;

    for (i = 0x80; i; i >>= 1) {
        /* Set the data bit. */
        if (octet & i) {
            SDA_HIGH();
        } else {
            SDA_LOW();
        }
        /* Wait for data to stabelize. */
        TwDelay(TWI_DELAY);
        /* Toggle the clock. */
        SCL_HIGH();
        TwDelay(2 * TWI_DELAY);
        SCL_LOW();
        TwDelay(TWI_DELAY);
    }

    /* Set data line high to receive the ACK bit. */
    SDA_HIGH();

    /* ACK should appear shortly after the clock's rising edge. */
    SCL_HIGH();
    TwDelay(2 * TWI_DELAY);
    if (SDA_STAT()) {
        i = -1;
    } else {
        i = 0;
    }
    SCL_LOW();

    return i;
}
Пример #2
0
void ICACHE_RAM_ATTR twi_reply(uint8_t ack)
{
  // transmit master read ready signal, with or without ack
  if (ack) {
    //TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
	SCL_HIGH();		// _BV(TWINT)
	twi_ack = 1; 	// _BV(TWEA)
  } else {
	//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
	SCL_HIGH();		// _BV(TWINT)
	twi_ack = 0;	// ~_BV(TWEA)
  }
}
Пример #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;
}
Пример #4
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;
}
static void TwAck(void)
{
    SDA_LOW();
    SCL_HIGH();
    TwDelay(2 * TWI_DELAY);
    SCL_LOW();
    SDA_HIGH();
}
Пример #6
0
/*!
 * \brief Initialize TWI interface.
 *
 * The specified slave address is used only, if the local system
 * is running as a slave. Anyway, care must be taken that it doesn't
 * conflict with another connected device.
 *
 * \param sla Slave address, must be specified as a 7-bit address,
 *            always lower than 128.
 *
 * \return Always 0.
 *
 */
int TwBbifInit(void)
{
    SDA_HIGH();
    SCL_HIGH();
    TWI_ENABLE();
    twibb_initialized = 1;

    return 0;
}
Пример #7
0
/*
 * Rising edge on the data line while the clock line is high indicates
 * a stop condition.
 *
 * Entry: SCL low, SDA any
 * Exit: SCL high, SDA high
 */
static void TwStop(void)
{
    SDA_LOW();
    TwDelay(TWI_DELAY);
    SCL_HIGH();
    TwDelay(2 * TWI_DELAY);
    SDA_HIGH();
    TwDelay(8 * TWI_DELAY);
}
void TwInit(void)
{
    SDA_HIGH();
    SCL_HIGH();

    outr(TWI_SDA_COD_REG, _BV(TWI_SDA_BIT));
    outr(TWI_SCL_COD_REG, _BV(TWI_SCL_BIT));
    outr(TWI_SDA_PE_REG, _BV(TWI_SDA_BIT));
    outr(TWI_SCL_PE_REG, _BV(TWI_SCL_BIT));
}
Пример #9
0
/*
 * Falling edge on the data line while the clock line is high indicates
 * a start condition.
 *
 * Entry: SCL any, SDA any
 * Exit: SCL low, SDA low
 */
static void TwStart(void)
{
    SDA_HIGH();
    TwDelay(TWI_DELAY);
    SCL_HIGH();
    TwDelay(TWI_DELAY);
    SDA_LOW();
    TwDelay(TWI_DELAY);
    SCL_LOW();
    TwDelay(TWI_DELAY);
}
Пример #10
0
void ICACHE_RAM_ATTR twi_releaseBus(void)
{
	// release bus
	//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
	SCL_HIGH();		// _BV(TWINT)
	twi_ack = 1; 	// _BV(TWEA)
	SDA_HIGH();

	// update twi state
	twi_state = TWI_READY;
}
Пример #11
0
void ICACHE_RAM_ATTR twi_stop(void)
{
	// send stop condition
	//TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
	SCL_HIGH();		// _BV(TWINT)
	twi_ack = 1;	// _BV(TWEA)
	twi_delay(5);	// Maybe this should be here
	SDA_HIGH();		// _BV(TWSTO)
	// update twi state
	twi_state = TWI_READY;
}
Пример #12
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;
}
Пример #13
0
static bool twi_write_bit(bool bit) {
  uint32_t i = 0;
  SCL_LOW();
  if (bit) SDA_HIGH();
  else SDA_LOW();
  twi_delay(twi_dcount+1);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);// Clock stretching
  twi_delay(twi_dcount);
  return true;
}
Пример #14
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;
}
Пример #15
0
// SDA 0->1 while SCL=1
void i2c_stop(alt_u32 clk_base, alt_u32 data_base){
    // assume SCL = 0
    
    SDA_DIR_OUT(data_base);  // data output enabled
    SDA_LOW(data_base); // Data Low
    //SCL_DELAY; 
    SCL_HIGH(clk_base);  // clock high
    SCL_DELAY; // clock high long delay
    SDA_HIGH(data_base); // data high
    SCL_DELAY; // data high delay
}
Пример #16
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;
}
Пример #17
0
static bool twi_write_stop(void){
  uint32_t i = 0;
  SCL_LOW();
  SDA_LOW();
  twi_delay(twi_dcount);
  SCL_HIGH();
  while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit); // Clock stretching
  twi_delay(twi_dcount);
  SDA_HIGH();
  twi_delay(twi_dcount);
  return true;
}
Пример #18
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;
}
Пример #19
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;
}    
Пример #20
0
static bool ICACHE_FLASH_ATTR twi_write_stop(void)
{
	unsigned int i = 0;
	SCL_LOW();
	SDA_LOW();
	twi_delay(twi_dcount);
	SCL_HIGH();
	while (SCL_READ() == 0 && (i++) < twi_clockStretchLimit);	// Clock stretching
	twi_delay(twi_dcount);
	SDA_HIGH();
	twi_delay(twi_dcount);

	return true;
}
Пример #21
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;
}
Пример #22
0
//SDA 1->0 while SCL=1
void i2c_start(alt_u32 clk_base, alt_u32 data_base){
    
    // make sure it is in normal state
    SDA_DIR_OUT(data_base);  // data output enabled
    
    
    
    // start condition
    SDA_HIGH(data_base); // data high
    SCL_HIGH(clk_base);
    SCL_DELAY;
     
    SDA_LOW(data_base); // data low
    SCL_DELAY; 
    SCL_LOW(clk_base); // clock low
    SCL_DELAY;
}
Пример #23
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;
}
Пример #24
0
/*
 * Toggles in a single byte in master mode.
 *
 * Entry: SCL low, SDA any
 * Exit: SCL low, SDA high
 */
static uint8_t TwGet(void)
{
    uint8_t rc = 0;
    int i;

    /* SDA is input. */
    SDA_HIGH();
    TwDelay(TWI_DELAY);
    for (i = 0x80; i; i >>= 1) {
        TwDelay(TWI_DELAY);
        /* Data should appear shortly after the clock's rising edge. */
        SCL_HIGH();
        TwDelay(2 * TWI_DELAY);
        /* SDA read. */
        if (SDA_STAT()) {
            rc |= i;
        }
        SCL_LOW();
    }
    return rc;
}
Пример #25
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;
}
Пример #26
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;
	}
}