Example #1
0
File: i2c_api.c Project: pan-/mbed
int i2c_slave_read(i2c_t *obj, char *data, int length) {
    int count = 0;
    int status;
    
    do {
        i2c_clear_SI(obj);
        i2c_wait_SI(obj);
        status = i2c_status(obj);
        if((status == 0x80) || (status == 0x90)) {
            data[count] = I2C_DAT(obj) & 0xFF;
        }
        count++;
    } while (((status == 0x80) || (status == 0x90) ||
            (status == 0x060) || (status == 0x70)) && (count < length));
 
    // Clear old status and wait for Serial Interrupt. 
    i2c_clear_SI(obj);
    i2c_wait_SI(obj);
 
    // Obtain new status.
    status = i2c_status(obj);
 
    if(status != 0xA0) {
        i2c_stop(obj);
    }
 
    i2c_clear_SI(obj);
    
    return count;
}
Example #2
0
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
    int i, status;
    
    status = i2c_start(obj);
    
    if ((status != 0x10) && (status != 0x08)) {
        i2c_stop(obj);
        return status;
    }
    
    status = i2c_do_write(obj, (address & 0xFE), 1);
    if (status != 0x18) {
        i2c_stop(obj);
        return status;
    }
    
    for (i=0; i<length; i++) {
        status = i2c_do_write(obj, data[i], 0);
        if(status != 0x28) {
            i2c_stop(obj);
            return status;
        }
    }
    
    i2c_clear_SI(obj);
    
    // If not repeated start, send stop.
    if (stop) {
        i2c_stop(obj);
    }
    
    return 0;
}
Example #3
0
inline int i2c_start(i2c_t *obj) {
    int status = 0;
    int isInterrupted = I2C_CONSET(obj) & (1 << 3);

    // 8.1 Before master mode can be entered, I2CON must be initialised to:
    //  - I2EN STA STO SI AA - -
    //  -  1    0   0   x  x - -
    // if AA = 0, it can't enter slave mode
    i2c_conclr(obj, 1, 1, 0, 1);

    // The master mode may now be entered by setting the STA bit
    // this will generate a start condition when the bus becomes free
    i2c_conset(obj, 1, 0, 0, 1);
    // Clearing SI bit when it wasn't set on entry can jump past state
    // 0x10 or 0x08 and erroneously send uninitialized slave address.
    if (isInterrupted)
        i2c_clear_SI(obj);

    i2c_wait_SI(obj);
    status = i2c_status(obj);

    // Clear start bit now that it's transmitted
    i2c_conclr(obj, 1, 0, 0, 0);
    return status;
}
Example #4
0
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
    int i, status;

    status = i2c_start(obj);

    if ((status != 0x10) && (status != 0x08)) {
        i2c_stop(obj);
        return status;
    }

    status = i2c_do_write(obj, (address & 0xFE));
    if (status != 0x18) {
        i2c_stop(obj);
        return status;
    }

    for (i=0; i<length; i++) {
        status = i2c_do_write(obj, data[i]);
        if(status != 0x28) {
            i2c_stop(obj);
            return status;
        }
    }

    i2c_clear_SI(obj);

    if (stop) {
      if(i2c_stop(obj) == 1)
            return 1;       
    }

    return 0;
}
Example #5
0
inline void i2c_stop(i2c_t *obj) {
    // write the stop bit
    i2c_conset(obj, 0, 1, 0, 0);
    i2c_clear_SI(obj);
    
    // wait for STO bit to reset
    while(I2C_CONSET(obj) & (1 << 4));
}
Example #6
0
static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
    // write the data
    I2C_DAT(obj) = value;
    
    // clear SI to init a send
    i2c_clear_SI(obj);
    
    // wait and return status
    i2c_wait_SI(obj);
    return i2c_status(obj);
}
Example #7
0
int i2c_slave_read(i2c_t *obj, char *data, int length) {
    int count = 0;
    int status;
    
    do {
        i2c_clear_SI(obj);
        i2c_wait_SI(obj);
        status = i2c_status(obj);
        if((status == 0x80) || (status == 0x90)) {
            data[count] = I2C_DAT(obj) & 0xFF;
        }
        count++;
    } while (((status == 0x80) || (status == 0x90) ||
            (status == 0x060) || (status == 0x70)) && (count < length));
    
    if(status != 0xA0) {
        i2c_stop(obj);
    }
    
    i2c_clear_SI(obj);
    
    return count;
}
Example #8
0
inline int i2c_stop(i2c_t *obj) {
    int timeout = 0;

    // write the stop bit
    i2c_conset(obj, 0, 1, 0, 0);
    i2c_clear_SI(obj);
    
    // wait for STO bit to reset
    while(I2C_CONSET(obj) & (1 << 4)) {
        timeout ++;
        if (timeout > 100000) return 1;
    }

    return 0;
}
Example #9
0
static inline int i2c_do_read(i2c_t *obj, int last) {
    // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack)
    if(last) {
        i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK
    } else {
        i2c_conset(obj, 0, 0, 0, 1); // send a ACK
    }
    
    // accept byte
    i2c_clear_SI(obj);
    
    // wait for it to arrive
    i2c_wait_SI(obj);
    
    // return the data
    return (I2C_DAT(obj) & 0xFF);
}
Example #10
0
int i2c_slave_write(i2c_t *obj, const char *data, int length) {
    int count = 0;
    int status;
    
    if(length <= 0) {
        return(0);
    }
    
    do {
        status = i2c_do_write(obj, data[count], 0);
        count++;
    } while ((count < length) && (status == 0xB8));
    
    if ((status != 0xC0) && (status != 0xC8)) {
        i2c_stop(obj);
    }
    
    i2c_clear_SI(obj);
    
    return(count);
}