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