Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of eMPL_MPU6050 by
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 | } |
