Пример #1
0
//------------------------------------------------------------------------------
// Writes a byte to I2C and checks acknowledge
// returns 0 on success
//------------------------------------------------------------------------------
i2cError_t i2cSoftWriteByte(uint8_t txByte)
{
    uint8_t mask; 
    i2cError_t err=0;
  
    for (mask = 0x80; mask > 0; mask >>= 1)   //shift bit for masking (8 times)
    {
        if ((mask & txByte) == 0) {
            I2C_SDA_LO();               //write a bit to SDA-Line
        }
        else {
            I2C_SDA_HI();
        }
        udelay(1);
        I2C_SCL_HI();
        udelay(5);
        I2C_SCL_LO();
        udelay(1);
    }
    I2C_SDA_IN();                       //release SDA-line
    I2C_SCL_HI();                       //clk #9 for ack
    udelay(5);
    if (I2C_SDA_GET() != 0) {
        err = I2C_ACK_ERROR;            //check ack from i2c slave
    }
    I2C_SCL_LO();
    udelay(5);
    //udelay(20);                       //delay to see the package on scope
    I2C_SDA_OUT();
    return err;                         //return error code
}
Пример #2
0
//------------------------------------------------------------------------------
// Reads a byte from I2C
// Returns the byte received
// note: timing (delay) may have to be changed for different microcontroller
//------------------------------------------------------------------------------
uint8_t i2cSoftReadByte(i2cAck_t ack)
{
    uint8_t mask, rxByte=0;

    I2C_SDA_IN();                       //release SDA-line
    for (mask = 0x80; mask > 0; mask >>= 1)   //shift bit for masking 
    {
        I2C_SCL_HI();                   //start clock on SCL-line
        udelay(4);
        if (I2C_SDA_GET() != 0) {
            rxByte = (rxByte | mask);   //read bit
        }
        I2C_SCL_LO();
        udelay(1);                       //data hold time
    }
    if (ack) {
        I2C_SDA_LO();                   //send acknowledge if necessary
    } else {
        I2C_SDA_HI();
    } 
    udelay(1);      
    I2C_SCL_HI();                       //clk #9 for ack
    udelay(5);      
    I2C_SCL_LO();
    I2C_SDA_IN();                       //release SDA-line
    udelay(5);
    //udelay(20);                       //delay to see the package on scope
    return rxByte;                      //return received byte
}
Пример #3
0
/*
 * Toggles in a single byte in master mode.
 *
 * Entry: SCL low, SDA any
 * Exit: SCL low, SDA low with ack set, high else
 *
 * Change SDA only when SCL is low!
 * Sample SDA short before setting SCL low!
 */
static uint8_t TwGet(GPIO_TWICB* icb, uint8_t ack)
{
    uint8_t rc = 0;
    int i;

    /* SDA is input. */
    I2C_SDA_HI();
    NutMicroDelay (1 * icb->delay_unit);
    for (i = 0x80; i; i >>= 1) {
        NutMicroDelay (2 * icb->delay_unit);
        I2C_SCL_HI();
        NutMicroDelay (2 * icb->delay_unit);
        while(I2C_SCL_GET() == 0)
        {
            /* Clock stretching*/
            NutMicroDelay (2 * icb->delay_unit);
        }
        if (I2C_SDA_GET()) {
            rc |= i;
        }
        I2C_SCL_LO();
    }
    if (ack)
    {
        /* Master sets acknowledge */
        I2C_SDA_LO();
    }
    NutMicroDelay (2 * icb->delay_unit);
   I2C_SCL_HI();
    NutMicroDelay (2 * icb->delay_unit);
    I2C_SCL_LO();
    NutMicroDelay (2 * icb->delay_unit);
    return rc;
}
Пример #4
0
//------------------------------------------------------------------------------
//Initializes the ports for I2C
//------------------------------------------------------------------------------
void i2cSoftInit(void)
{
    I2C_SDA_OUT();
    I2C_SCL_OUT();
    I2C_SDA_LO();
    I2C_SCL_LO();
    I2C_SDA_HI();
    I2C_SCL_HI();
}
Пример #5
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(GPIO_TWICB* icb)
{
    I2C_SDA_LO();
    NutMicroDelay (icb->delay_unit);
    I2C_SCL_HI();
    NutMicroDelay (2 * icb->delay_unit);
    I2C_SDA_HI();
    NutMicroDelay (8 * icb->delay_unit);
}
Пример #6
0
/*
 * Toggles out a single byte in master mode.
 *
 * Entry: SCL low, SDA any
 * Exit: SCL low, SDA high
 *
 * Change SDA only when SCL is low!
 * Sample SDA short before setting SCL low!
 */
static int TwPut(GPIO_TWICB* icb, uint8_t octet)
{
    int i;

    for (i = 0x80; i; i >>= 1) {
        /* Set the data bit. */
        if (octet & i) {
            I2C_SDA_HI();
        } else {
            I2C_SDA_LO();
        }
        /* Wait for data to stabilize. */
        NutMicroDelay (2 * icb->delay_unit);
        /* Toggle the clock. */
        I2C_SCL_HI();
        NutMicroDelay (2 * icb->delay_unit);
        while(I2C_SCL_GET() == 0)
        {
            /* Clock stretching*/
            NutMicroDelay (2 * icb->delay_unit);
        }
        I2C_SCL_LO();
    }

    /* Release data line to receive the ACK bit. */
    I2C_SDA_HI();
    NutMicroDelay (2 * icb->delay_unit);
    I2C_SCL_HI();
    NutMicroDelay (2 * icb->delay_unit);
    if (I2C_SDA_GET()) {
        i = -1;
    } else {
        i = 0;
    }
    I2C_SCL_LO();
    NutMicroDelay (2 * icb->delay_unit);

    return i;
}