Example #1
0
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
    int i, status;

    // full reset
    i2c_reg_reset(obj);

    status = i2c_start(obj);

    if ((status == 0xff)) {
        i2c_stop(obj);
        i2c_wait_STOP(obj);
        return I2C_ERROR_BUS_BUSY;
    }
    
    /**/
    status = REG(CR2.UINT32);
    status = REG(SR2.UINT32);
    /**/

    status = i2c_do_write(obj, address);
    if (status & 0x10) {
        i2c_stop(obj);
        i2c_wait_STOP(obj);
        return I2C_ERROR_NO_SLAVE;
    }

    /**/
    status = REG(CR2.UINT32);
    status = REG(SR2.UINT32);
    /**/
    for (i=0; i<length; i++) {
    /**/
    status = REG(CR2.UINT32);
    status = REG(SR2.UINT32);
    /**/
        status = i2c_do_write(obj, data[i]);
        if(status & 0x10) {
            i2c_stop(obj);
            i2c_wait_STOP(obj);
            return i;
        }
    }

    i2c_wait_TEND(obj);

    // If not repeated start, send stop.
    if (stop) {
        i2c_stop(obj);
        i2c_wait_STOP(obj);
    }

    return length;
}
Example #2
0
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
    // determine the SPI to use
    I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
    I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
    obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
    MBED_ASSERT((int)obj->i2c != NC);

    // enable power
    i2c_power_enable(obj);

    // set default frequency at 100k
    i2c_frequency(obj, 100000);

    // full reset
    i2c_reg_reset(obj);

    pinmap_pinout(sda, PinMap_I2C_SDA);
    pinmap_pinout(scl, PinMap_I2C_SCL);
}
Example #3
0
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
    int count = 0;
    int status;
    int value;
    volatile uint32_t work_reg = 0;

    // full reset
    i2c_reg_reset(obj);
    obj->dummy = 1;
    
    status = i2c_start(obj);

    if (status == 0xff) {
        i2c_stop(obj);
        i2c_wait_STOP(obj);
        return I2C_ERROR_BUS_BUSY;
    }

    status = i2c_do_write(obj, (address | 0x01));
    if (status & 0x01) {
        i2c_stop(obj);
        i2c_wait_STOP(obj);
        return I2C_ERROR_NO_SLAVE;
    }
    
    /* wati RDRF */
    i2c_wait_RDRF(obj);
    /* check ACK/NACK */
    if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
        /* Slave sends NACK */
        i2c_stop(obj);
        // dummy read
        value = REG(DRR.UINT32);
        i2c_wait_STOP(obj);
        return I2C_ERROR_NO_SLAVE;
    }
    
    // Read in all except last byte
    if (length > 2) {
        for (count = 0; count < (length - 1); count++) {
            if (count == (length - 2)) {
                value = i2c_do_read(obj, 1);
            } else if ((length >= 3) && (count == (length - 3))) {
                value = i2c_do_read(obj, 2);
            } else {
                value = i2c_do_read(obj, 0);
            }
            status = i2c_status(obj);
            if (status & 0x10) {
                i2c_stop(obj);
                i2c_wait_STOP(obj);
                return count;
            }
            data[count] = (char) value;
        }
    } else if (length == 2) {
        /* Set MR3 WATI bit is 1 */;
        REG(MR3.UINT32) |= (1 << 6);
        // dummy read
        value = REG(DRR.UINT32);
        // wait for it to arrive
        i2c_wait_RDRF(obj);
        // send a NOT ACK
        REG(MR3.UINT32) |= (1 <<4);
        REG(MR3.UINT32) |=  (1 <<3);
        REG(MR3.UINT32) &= ~(1 <<4);
        data[count] = (char)REG(DRR.UINT32);
        count++;
    } else if (length == 1) {
        /* Set MR3 WATI bit is 1 */;
        REG(MR3.UINT32) |= (1 << 6);
        // send a NOT ACK
        REG(MR3.UINT32) |= (1 <<4);
        REG(MR3.UINT32) |=  (1 <<3);
        REG(MR3.UINT32) &= ~(1 <<4);
        // dummy read
        value = REG(DRR.UINT32);
    } else {
        // Do Nothing
    }

    // read in last byte
    i2c_wait_RDRF(obj);
    // If not repeated start, send stop.
    if (stop) {
        /* RIICnSR2.STOP = 0 */
        REG(SR2.UINT32) &= ~(1 << 3);
        /* RIICnCR2.SP   = 1 */
        REG(CR2.UINT32) |= (1 << 3);
        /* RIICnDRR read */
        value = REG(DRR.UINT32) & 0xFF;
        data[count] = (char) value;
        /* RIICnMR3.WAIT = 0 */
        REG(MR3.UINT32) &= ~(1 << 6);
        i2c_wait_STOP(obj);
    } else {
        /* RIICnDRR read */
        value = REG(DRR.UINT32) & 0xFF;
        data[count] = (char) value;
    }

    return length;
}
Example #4
0
void i2c_frequency(i2c_t *obj, int hz) {
    float64_t pclk_val;
    float64_t wait_utime;
    volatile float64_t bps;
    volatile float64_t L_time;         /* H Width period */
    volatile float64_t H_time;         /* L Width period */
    uint32_t tmp_L_width;
    uint32_t tmp_H_width;
    uint32_t remainder;
    uint32_t wk_cks = 0;

    /* set PCLK */
    if (false == RZ_A1_IsClockMode0()) {
        pclk_val = (float64_t)CM1_RENESAS_RZ_A1_P0_CLK;
    } else {
        pclk_val = (float64_t)CM0_RENESAS_RZ_A1_P0_CLK;
    }

    /* Min 10kHz, Max 400kHz */
    if (hz < 10000) {
        bps = 10000;
    } else if (hz > 400000) {
        bps = 400000;
    } else {
        bps = (float64_t)hz;
    }

    /* Calculation L width time */
    L_time = (1 / (2 * bps));   /* Harf period of frequency */
    H_time = L_time;

    /* Check I2C mode of Speed */
    if (bps > 100000) {
        /* Fast-mode */
        L_time -= 102E-9;    /* Falling time of SCL clock. */
        H_time -= 138E-9;    /* Rising time of SCL clock. */
        /* Check L wideth */
        if (L_time < 1.3E-6) {
            /* Wnen L width less than 1.3us */
            /* Subtract Rise up and down time for SCL from H/L width */
            L_time = 1.3E-6;
            H_time = (1 / bps) - L_time - 138E-9 - 102E-9;
        }
    }

    tmp_L_width   = (uint32_t)(L_time * pclk_val * 10);
    tmp_L_width >>= 1;
    wk_cks++;
    while (tmp_L_width >= 341) {
        tmp_L_width >>= 1;
        wk_cks++;
    }
    remainder   = tmp_L_width % 10;
    tmp_L_width = ((tmp_L_width + 9) / 10) - 3;       /* carry */

    tmp_H_width   = (uint32_t)(H_time * pclk_val * 10);
    tmp_H_width >>= wk_cks;
    if (remainder == 0) {
        tmp_H_width   = ((tmp_H_width + 9) / 10) - 3; /* carry */
    } else {
        remainder    += tmp_H_width % 10;
        tmp_H_width   = (tmp_H_width / 10) - 3;
        if (remainder > 10) {
            tmp_H_width += 1;                         /* fine adjustment */
        }
    }
    /* timeout of BBSY bit is minimum low width by frequency */
    /* so timeout calculates "(low width) * 2" by frequency */
    wait_utime = (L_time * 2) * 1000000;
    /* 1 wait of BBSY bit is about 0.3us. if it's below 0.3us, wait count is set as 1. */
    if (wait_utime <= 0.3) {
        obj->bbsy_wait_cnt = 1;
    } else {
        obj->bbsy_wait_cnt = (int)(wait_utime / 0.3);
    }


    /* I2C Rate */
    obj->pclk_bit  = (uint8_t)(0x10 * wk_cks);        /* P_phi / xx */
    obj->width_low = (uint8_t)(tmp_L_width | 0x000000E0);
    obj->width_hi  = (uint8_t)(tmp_H_width | 0x000000E0);

    /* full reset */
    i2c_reg_reset(obj);
}
Example #5
0
void i2c_abort_asynch(i2c_t *obj)
{
    i2c_data[obj->i2c.i2c].async_obj = NULL;
    i2c_irqs_set(obj, 0);
    i2c_reg_reset(obj);
}