예제 #1
0
//
// Send a START Condition
//
// The SDA and SCL should already be high.
// 
// The SDA and SCL will both be low after this function.
// When writing the address, the Master makes them high.
// 
// Return value:
//   true  : software i2c bus is okay.
//   false : failed, some kind of hardware bus error.
//
boolean SoftwareWire::i2c_start(void)
{
  i2c_sda_hi();              // can perhaps be removed some day ? if the rest of the code is okay
  i2c_scl_hi();              // can perhaps be removed some day ? if the rest of the code is okay

  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);
    
  // Both the sda and scl should be high.
  // If not, there might be a hardware problem with the i2c bus signal lines.
  // This check was added to prevent that a shortcut of sda would be seen as a valid ACK
  // from a i2c Slave.
  uint8_t sda_status = i2c_sda_read();
  uint8_t scl_status = i2c_scl_read();
  if(sda_status == 0 || scl_status == 0)
  {
    return(false);
  }
  else
  {
    i2c_sda_lo();
    
    if (_i2cdelay != 0)
      delayMicroseconds(_i2cdelay);
  
    i2c_scl_lo();
    
    if (_i2cdelay != 0)
      delayMicroseconds(_i2cdelay);
  }
  return(true);
}
예제 #2
0
// Send a STOP Condition
//
void SoftwareWire::i2c_stop(void)
{
  i2c_sda_lo();
  i2c_scl_hi();
  
  // Check if clock stretching by the Slave should be detected.
  if( _stretch)
  {
    // Wait until the clock is high, the Slave could keep it low for clock stretching.
    // Clock pulse stretching during a stop condition seems odd, but when
    // the Slave is an Arduino, it might happen.
    unsigned long prevMillis = millis();
    while( i2c_scl_read() == 0)
    {
      if( millis() - prevMillis >= _timeout)
        break;
    };
  }
   
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);

  i2c_sda_hi();
  
  // A delay after the STOP for safety.
  // It is not known how fast the next START will happen.
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);
}
예제 #3
0
void SoftI2CMaster::i2c_writebit( uint8_t c )
{
    if ( c > 0 ) {
        i2c_sda_hi();
    } else {
        i2c_sda_lo();
    }

    i2c_scl_hi();
    _delay_us(i2cbitdelay);

    i2c_scl_lo();
    _delay_us(i2cbitdelay);

    if ( c > 0 ) {
        i2c_sda_lo();
    }
    _delay_us(i2cbitdelay);
}
예제 #4
0
파일: soft_i2c.c 프로젝트: aczid/jxd393_dev
void soft_i2c_init(void){
    // input with pull-up in input mode, push/pull in output mode
    GPIOA->CR1 = 0x06;
    // interrupts disabled in input mode, output at 2MHz in output mode
    GPIOA->CR2 = 0x00;
    i2c_sda_lo();
    i2c_sclk_hi();
    i2c_bit_delay();
    started = 0;
}
예제 #5
0
파일: soft_i2c.c 프로젝트: aczid/jxd393_dev
void soft_i2c_stop(void){
    i2c_sda_lo();
    i2c_bit_delay();
    while(soft_i2c_read_sclk() == 0){
        // add timeout
    }
    i2c_bit_delay();
    if(soft_i2c_read_sda() == 0){
        // arbitration lost
        return;
    }
    i2c_bit_delay();
    started = 0;
}
예제 #6
0
// Send a START Condition
//
void SoftI2CMaster::i2c_start(void)
{
    // set both to high at the same time
    //I2C_DDR &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
    //*_sclDirReg &=~ (_sdaBitMask | _sclBitMask);
    i2c_sda_hi();
    i2c_scl_hi();

    _delay_us(i2cbitdelay);
   
    i2c_sda_lo();
    _delay_us(i2cbitdelay);

    i2c_scl_lo();
    _delay_us(i2cbitdelay);
}
예제 #7
0
파일: soft_i2c.c 프로젝트: aczid/jxd393_dev
void soft_i2c_writebit(uint8_t bit){
    if(bit){
        i2c_sda_hi();
    } else {
        i2c_sda_lo();
    }
    i2c_bit_delay();
    while(soft_i2c_read_sclk() == 0){
        // add timeout
    }
    if(bit && soft_i2c_read_sda() == 0){
        // arbitration lost
        return;
    }
    i2c_bit_delay();
    i2c_sclk_lo();
}
예제 #8
0
void SoftI2CMaster::i2c_repstart(void)
{
    // set both to high at the same time (releases drive on both lines)
    //I2C_DDR &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
    //*_sclDirReg &=~ (_sdaBitMask | _sclBitMask);
    i2c_sda_hi();
    i2c_scl_hi();

    i2c_scl_lo();                           // force SCL low
    _delay_us(i2cbitdelay);

    i2c_sda_release();                      // release SDA
    _delay_us(i2cbitdelay);

    i2c_scl_release();                      // release SCL
    _delay_us(i2cbitdelay);

    i2c_sda_lo();                           // force SDA low
    _delay_us(i2cbitdelay);
}
예제 #9
0
//
// The i2c_writebit and i2c_readbit could be make "inline", but that
// didn't increase the speed, and the code size increases.
//
// The sda is low after the start condition.
// Therefor the sda is low for the first bit.
//
void SoftwareWire::i2c_writebit(uint8_t c)
{
  if(c==0)
  {
    i2c_sda_lo();
  }
  else
  {
    i2c_sda_hi();
  }
  
  if (_i2cdelay != 0)               // This delay is not needed, but it makes it safer
    delayMicroseconds(_i2cdelay);   // This delay is not needed, but it makes it safer
  
  i2c_scl_hi();                     // clock high: the Slave will read the sda signal
  
  // Check if clock stretching by the Slave should be detected.
  if( _stretch)
  {
    // If the Slave was strechting the clock pulse, the clock would not go high immediately.
    // For example if the Slave is an Arduino, that has other interrupts running (for example Serial data).
    unsigned long prevMillis = millis();
    while( i2c_scl_read() == 0)
    {
      if( millis() - prevMillis >= _timeout)
        break;
    };
  }

  // After the clock stretching, the clock must be high for the normal duration.
  // That is why this delay has still to be done.
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);

  i2c_scl_lo();
  
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);
}
예제 #10
0
//
// Repeated START instead of a STOP
// 
// TODO: check if the repeated start actually works.
//
void SoftwareWire::i2c_repstart(void)
{
  i2c_sda_hi();
//  i2c_scl_hi();               // ??????

  i2c_scl_lo();                         // force SCL low
  
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);

  i2c_sda_hi();                        // release SDA
  
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);

  i2c_scl_hi();                        // release SCL
  
  // Check if clock stretching by the Slave should be detected.
  if( _stretch)
  {
    // If the Slave was strechting the clock pulse, the clock would not go high immediately.
    // For example if the Slave is an Arduino, that has other interrupts running (for example Serial data).
    unsigned long prevMillis = millis();
    while( i2c_scl_read() == 0)
    {
      if( millis() - prevMillis >= _timeout)
        break;
    };
  }
  
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);

  i2c_sda_lo();                        // force SDA low
  
  if (_i2cdelay != 0)
    delayMicroseconds(_i2cdelay);
}