library for MPU6050 and MPU9250, supports both I2C and SPI
Dependents: Seeed_nRF51822_MPU9250
mbed_i2c.c@0:972f3778c19c, 2015-12-10 (annotated)
- Committer:
- yihui
- Date:
- Thu Dec 10 07:39:48 2015 +0000
- Revision:
- 0:972f3778c19c
initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:972f3778c19c | 1 | |
yihui | 0:972f3778c19c | 2 | #include <stdio.h> |
yihui | 0:972f3778c19c | 3 | #include "i2c_api.h" |
yihui | 0:972f3778c19c | 4 | #include "gpio_api.h" |
yihui | 0:972f3778c19c | 5 | #include "nrf_delay.h" |
yihui | 0:972f3778c19c | 6 | |
yihui | 0:972f3778c19c | 7 | static i2c_t mbed_i2c_object = {0,}; |
yihui | 0:972f3778c19c | 8 | PinName mbed_i2c_sda_pin = NC; |
yihui | 0:972f3778c19c | 9 | PinName mbed_i2c_scl_pin = NC; |
yihui | 0:972f3778c19c | 10 | |
yihui | 0:972f3778c19c | 11 | void mbed_i2c_init(PinName sda, PinName scl) |
yihui | 0:972f3778c19c | 12 | { |
yihui | 0:972f3778c19c | 13 | if (mbed_i2c_sda_pin == NC) { |
yihui | 0:972f3778c19c | 14 | mbed_i2c_sda_pin = sda; |
yihui | 0:972f3778c19c | 15 | mbed_i2c_scl_pin = scl; |
yihui | 0:972f3778c19c | 16 | } |
yihui | 0:972f3778c19c | 17 | |
yihui | 0:972f3778c19c | 18 | i2c_init(&mbed_i2c_object, sda, scl); |
yihui | 0:972f3778c19c | 19 | i2c_frequency(&mbed_i2c_object, 100000); |
yihui | 0:972f3778c19c | 20 | } |
yihui | 0:972f3778c19c | 21 | |
yihui | 0:972f3778c19c | 22 | int mbed_i2c_write(unsigned char slave_addr, |
yihui | 0:972f3778c19c | 23 | unsigned char reg_addr, |
yihui | 0:972f3778c19c | 24 | unsigned char length, |
yihui | 0:972f3778c19c | 25 | unsigned char const *data) |
yihui | 0:972f3778c19c | 26 | { |
yihui | 0:972f3778c19c | 27 | int i; |
yihui | 0:972f3778c19c | 28 | slave_addr = slave_addr << 1; |
yihui | 0:972f3778c19c | 29 | i2c_start(&mbed_i2c_object); |
yihui | 0:972f3778c19c | 30 | i2c_byte_write(&mbed_i2c_object, slave_addr); |
yihui | 0:972f3778c19c | 31 | i2c_byte_write(&mbed_i2c_object, reg_addr); |
yihui | 0:972f3778c19c | 32 | for (i = 0; i < length; i++) { |
yihui | 0:972f3778c19c | 33 | i2c_byte_write(&mbed_i2c_object, data[i]); |
yihui | 0:972f3778c19c | 34 | } |
yihui | 0:972f3778c19c | 35 | i2c_stop(&mbed_i2c_object); |
yihui | 0:972f3778c19c | 36 | return 0; |
yihui | 0:972f3778c19c | 37 | } |
yihui | 0:972f3778c19c | 38 | |
yihui | 0:972f3778c19c | 39 | int mbed_i2c_read(unsigned char slave_addr, |
yihui | 0:972f3778c19c | 40 | unsigned char reg_addr, |
yihui | 0:972f3778c19c | 41 | unsigned char length, |
yihui | 0:972f3778c19c | 42 | unsigned char *data) |
yihui | 0:972f3778c19c | 43 | { |
yihui | 0:972f3778c19c | 44 | slave_addr = slave_addr << 1; |
yihui | 0:972f3778c19c | 45 | i2c_write(&mbed_i2c_object, slave_addr, ®_addr, 1, 0); |
yihui | 0:972f3778c19c | 46 | return (i2c_read(&mbed_i2c_object, slave_addr, data, length, 1) == length) ? 0 : 1; |
yihui | 0:972f3778c19c | 47 | } |
yihui | 0:972f3778c19c | 48 | |
yihui | 0:972f3778c19c | 49 | int mbed_i2c_clear(PinName sda, PinName scl) |
yihui | 0:972f3778c19c | 50 | { |
yihui | 0:972f3778c19c | 51 | gpio_t sda_io, scl_io; |
yihui | 0:972f3778c19c | 52 | |
yihui | 0:972f3778c19c | 53 | if (mbed_i2c_object.i2c) { |
yihui | 0:972f3778c19c | 54 | mbed_i2c_object.i2c->PSELSCL = 31; |
yihui | 0:972f3778c19c | 55 | mbed_i2c_object.i2c->PSELSDA = 31; |
yihui | 0:972f3778c19c | 56 | } |
yihui | 0:972f3778c19c | 57 | |
yihui | 0:972f3778c19c | 58 | gpio_init_in(&sda_io, sda); |
yihui | 0:972f3778c19c | 59 | |
yihui | 0:972f3778c19c | 60 | if (!gpio_read(&sda_io)) { |
yihui | 0:972f3778c19c | 61 | printf("sda is always 0, i2c bus is not released\r\n"); |
yihui | 0:972f3778c19c | 62 | printf("try to clear i2c bus\r\n"); |
yihui | 0:972f3778c19c | 63 | gpio_init_out(&scl_io, scl); |
yihui | 0:972f3778c19c | 64 | |
yihui | 0:972f3778c19c | 65 | // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9 |
yihui | 0:972f3778c19c | 66 | // for slave to respond) to SCL line and wait for SDA come high. |
yihui | 0:972f3778c19c | 67 | for (int i = 0; i < 18; i++) { |
yihui | 0:972f3778c19c | 68 | gpio_write(&scl_io, 0); |
yihui | 0:972f3778c19c | 69 | nrf_delay_us(4); |
yihui | 0:972f3778c19c | 70 | gpio_write(&scl_io, 1); |
yihui | 0:972f3778c19c | 71 | nrf_delay_us(4); |
yihui | 0:972f3778c19c | 72 | } |
yihui | 0:972f3778c19c | 73 | |
yihui | 0:972f3778c19c | 74 | if (!gpio_read(&sda_io)) { |
yihui | 0:972f3778c19c | 75 | printf("warning! sda is still 0,, i2c bus is not released\r\n"); |
yihui | 0:972f3778c19c | 76 | } |
yihui | 0:972f3778c19c | 77 | } |
yihui | 0:972f3778c19c | 78 | |
yihui | 0:972f3778c19c | 79 | |
yihui | 0:972f3778c19c | 80 | if (mbed_i2c_object.i2c) { |
yihui | 0:972f3778c19c | 81 | mbed_i2c_init(sda, scl); |
yihui | 0:972f3778c19c | 82 | } |
yihui | 0:972f3778c19c | 83 | |
yihui | 0:972f3778c19c | 84 | return 0; |
yihui | 0:972f3778c19c | 85 | } |
yihui | 0:972f3778c19c | 86 | |
yihui | 0:972f3778c19c | 87 | void mbed_i2c_enable(void) |
yihui | 0:972f3778c19c | 88 | { |
yihui | 0:972f3778c19c | 89 | mbed_i2c_object.i2c->POWER = 1; |
yihui | 0:972f3778c19c | 90 | |
yihui | 0:972f3778c19c | 91 | mbed_i2c_init(mbed_i2c_sda_pin, mbed_i2c_scl_pin); |
yihui | 0:972f3778c19c | 92 | } |
yihui | 0:972f3778c19c | 93 | |
yihui | 0:972f3778c19c | 94 | void mbed_i2c_disable(void) |
yihui | 0:972f3778c19c | 95 | { |
yihui | 0:972f3778c19c | 96 | gpio_t sda_io, scl_io; |
yihui | 0:972f3778c19c | 97 | |
yihui | 0:972f3778c19c | 98 | mbed_i2c_object.i2c->PSELSCL = 31; |
yihui | 0:972f3778c19c | 99 | mbed_i2c_object.i2c->PSELSDA = 31; |
yihui | 0:972f3778c19c | 100 | |
yihui | 0:972f3778c19c | 101 | |
yihui | 0:972f3778c19c | 102 | mbed_i2c_object.i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; |
yihui | 0:972f3778c19c | 103 | mbed_i2c_object.i2c->POWER = 0; |
yihui | 0:972f3778c19c | 104 | |
yihui | 0:972f3778c19c | 105 | gpio_init_in(&sda_io, mbed_i2c_sda_pin); |
yihui | 0:972f3778c19c | 106 | gpio_init_in(&scl_io, mbed_i2c_scl_pin); |
yihui | 0:972f3778c19c | 107 | } |