MPU6050 library
Dependents: CSSE4011_BLE_IMU_Project_rev2 Seeed_Tiny_BLE_Get_Started nrf51822_fix_i2c_spi_conflict balanceboard ... more
mbed_i2c.c@1:6aedb937cb38, 2015-11-05 (annotated)
- Committer:
- yihui
- Date:
- Thu Nov 05 01:38:50 2015 +0000
- Revision:
- 1:6aedb937cb38
- Parent:
- 0:1b6dab73c06b
add mbed_i2c_clear() function; ; use mbed_i2c_clear to recover i2c bus when i2c is stuck
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:1b6dab73c06b | 1 | |
yihui | 1:6aedb937cb38 | 2 | #include <stdio.h> |
yihui | 0:1b6dab73c06b | 3 | #include "i2c_api.h" |
yihui | 1:6aedb937cb38 | 4 | #include "gpio_api.h" |
yihui | 1:6aedb937cb38 | 5 | #include "nrf_delay.h" |
yihui | 0:1b6dab73c06b | 6 | |
yihui | 1:6aedb937cb38 | 7 | static i2c_t mbed_i2c_object = {0,}; |
yihui | 0:1b6dab73c06b | 8 | |
yihui | 0:1b6dab73c06b | 9 | void mbed_i2c_init(PinName sda, PinName scl) |
yihui | 0:1b6dab73c06b | 10 | { |
yihui | 0:1b6dab73c06b | 11 | i2c_init(&mbed_i2c_object, sda, scl); |
yihui | 0:1b6dab73c06b | 12 | i2c_frequency(&mbed_i2c_object, 100000); |
yihui | 0:1b6dab73c06b | 13 | } |
yihui | 0:1b6dab73c06b | 14 | |
yihui | 0:1b6dab73c06b | 15 | int mbed_i2c_write(unsigned char slave_addr, |
yihui | 0:1b6dab73c06b | 16 | unsigned char reg_addr, |
yihui | 0:1b6dab73c06b | 17 | unsigned char length, |
yihui | 0:1b6dab73c06b | 18 | unsigned char const *data) |
yihui | 0:1b6dab73c06b | 19 | { |
yihui | 0:1b6dab73c06b | 20 | int i; |
yihui | 0:1b6dab73c06b | 21 | slave_addr = slave_addr << 1; |
yihui | 0:1b6dab73c06b | 22 | i2c_start(&mbed_i2c_object); |
yihui | 0:1b6dab73c06b | 23 | i2c_byte_write(&mbed_i2c_object, slave_addr); |
yihui | 0:1b6dab73c06b | 24 | i2c_byte_write(&mbed_i2c_object, reg_addr); |
yihui | 0:1b6dab73c06b | 25 | for (i = 0; i < length; i++) { |
yihui | 0:1b6dab73c06b | 26 | i2c_byte_write(&mbed_i2c_object, data[i]); |
yihui | 0:1b6dab73c06b | 27 | } |
yihui | 0:1b6dab73c06b | 28 | i2c_stop(&mbed_i2c_object); |
yihui | 0:1b6dab73c06b | 29 | return 0; |
yihui | 0:1b6dab73c06b | 30 | } |
yihui | 0:1b6dab73c06b | 31 | |
yihui | 0:1b6dab73c06b | 32 | int mbed_i2c_read(unsigned char slave_addr, |
yihui | 0:1b6dab73c06b | 33 | unsigned char reg_addr, |
yihui | 0:1b6dab73c06b | 34 | unsigned char length, |
yihui | 0:1b6dab73c06b | 35 | unsigned char *data) |
yihui | 0:1b6dab73c06b | 36 | { |
yihui | 0:1b6dab73c06b | 37 | slave_addr = slave_addr << 1; |
yihui | 0:1b6dab73c06b | 38 | i2c_write(&mbed_i2c_object, slave_addr, ®_addr, 1, 0); |
yihui | 0:1b6dab73c06b | 39 | return (i2c_read(&mbed_i2c_object, slave_addr, data, length, 1) == length) ? 0 : 1; |
yihui | 0:1b6dab73c06b | 40 | } |
yihui | 1:6aedb937cb38 | 41 | |
yihui | 1:6aedb937cb38 | 42 | int mbed_i2c_clear(PinName sda, PinName scl) |
yihui | 1:6aedb937cb38 | 43 | { |
yihui | 1:6aedb937cb38 | 44 | gpio_t sda_io, scl_io; |
yihui | 1:6aedb937cb38 | 45 | |
yihui | 1:6aedb937cb38 | 46 | if (mbed_i2c_object.i2c) { |
yihui | 1:6aedb937cb38 | 47 | mbed_i2c_object.i2c->PSELSCL = 31; |
yihui | 1:6aedb937cb38 | 48 | mbed_i2c_object.i2c->PSELSDA = 31; |
yihui | 1:6aedb937cb38 | 49 | } |
yihui | 1:6aedb937cb38 | 50 | |
yihui | 1:6aedb937cb38 | 51 | gpio_init_in(&sda_io, sda); |
yihui | 1:6aedb937cb38 | 52 | |
yihui | 1:6aedb937cb38 | 53 | if (!gpio_read(&sda_io)) { |
yihui | 1:6aedb937cb38 | 54 | printf("sda is always 0, i2c bus is not released\r\n"); |
yihui | 1:6aedb937cb38 | 55 | printf("try to clear i2c bus\r\n"); |
yihui | 1:6aedb937cb38 | 56 | gpio_init_out(&scl_io, scl); |
yihui | 1:6aedb937cb38 | 57 | |
yihui | 1:6aedb937cb38 | 58 | // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9 |
yihui | 1:6aedb937cb38 | 59 | // for slave to respond) to SCL line and wait for SDA come high. |
yihui | 1:6aedb937cb38 | 60 | for (int i = 0; i < 18; i++) { |
yihui | 1:6aedb937cb38 | 61 | gpio_write(&scl_io, 0); |
yihui | 1:6aedb937cb38 | 62 | nrf_delay_us(4); |
yihui | 1:6aedb937cb38 | 63 | gpio_write(&scl_io, 1); |
yihui | 1:6aedb937cb38 | 64 | nrf_delay_us(4); |
yihui | 1:6aedb937cb38 | 65 | } |
yihui | 1:6aedb937cb38 | 66 | |
yihui | 1:6aedb937cb38 | 67 | if (!gpio_read(&sda_io)) { |
yihui | 1:6aedb937cb38 | 68 | printf("warning! sda is still 0,, i2c bus is not released\r\n"); |
yihui | 1:6aedb937cb38 | 69 | } |
yihui | 1:6aedb937cb38 | 70 | } |
yihui | 1:6aedb937cb38 | 71 | |
yihui | 1:6aedb937cb38 | 72 | |
yihui | 1:6aedb937cb38 | 73 | if (mbed_i2c_object.i2c) { |
yihui | 1:6aedb937cb38 | 74 | mbed_i2c_init(sda, scl); |
yihui | 1:6aedb937cb38 | 75 | } |
yihui | 1:6aedb937cb38 | 76 | |
yihui | 1:6aedb937cb38 | 77 | return 0; |
yihui | 1:6aedb937cb38 | 78 | } |