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