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 mbed-dev by
targets/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c@163:1d4c9d0af1e9, 2017-04-11 (annotated)
- Committer:
- cpadua
- Date:
- Tue Apr 11 20:39:24 2017 +0000
- Revision:
- 163:1d4c9d0af1e9
- Parent:
- 160:d5399cc887bb
fixed i2c-api.c
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 144:ef7eb2e8f9f7 | 1 | /* mbed Microcontroller Library |
<> | 144:ef7eb2e8f9f7 | 2 | * Copyright (c) 2006-2015 ARM Limited |
<> | 144:ef7eb2e8f9f7 | 3 | * |
<> | 144:ef7eb2e8f9f7 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
<> | 144:ef7eb2e8f9f7 | 5 | * you may not use this file except in compliance with the License. |
<> | 144:ef7eb2e8f9f7 | 6 | * You may obtain a copy of the License at |
<> | 144:ef7eb2e8f9f7 | 7 | * |
<> | 144:ef7eb2e8f9f7 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
<> | 144:ef7eb2e8f9f7 | 9 | * |
<> | 144:ef7eb2e8f9f7 | 10 | * Unless required by applicable law or agreed to in writing, software |
<> | 144:ef7eb2e8f9f7 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
<> | 144:ef7eb2e8f9f7 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
<> | 144:ef7eb2e8f9f7 | 13 | * See the License for the specific language governing permissions and |
<> | 144:ef7eb2e8f9f7 | 14 | * limitations under the License. |
<> | 144:ef7eb2e8f9f7 | 15 | */ |
<> | 144:ef7eb2e8f9f7 | 16 | #include "i2c_api.h" |
<> | 144:ef7eb2e8f9f7 | 17 | #include "cmsis.h" |
<> | 144:ef7eb2e8f9f7 | 18 | #include "pinmap.h" |
<> | 144:ef7eb2e8f9f7 | 19 | #include "mbed_error.h" |
<> | 144:ef7eb2e8f9f7 | 20 | #include "SMM_MPS2.h" |
<> | 160:d5399cc887bb | 21 | #include "mbed_wait_api.h" |
<> | 144:ef7eb2e8f9f7 | 22 | #include "fpga.h" |
<> | 144:ef7eb2e8f9f7 | 23 | |
<> | 144:ef7eb2e8f9f7 | 24 | // Types |
<> | 144:ef7eb2e8f9f7 | 25 | #undef FALSE |
<> | 144:ef7eb2e8f9f7 | 26 | #undef TRUE |
<> | 144:ef7eb2e8f9f7 | 27 | #define FALSE 0 |
<> | 144:ef7eb2e8f9f7 | 28 | #define TRUE 1 |
<> | 144:ef7eb2e8f9f7 | 29 | |
<> | 144:ef7eb2e8f9f7 | 30 | // TSC I2C controller |
<> | 144:ef7eb2e8f9f7 | 31 | #define TSC_I2C_ADDR 0x82 |
<> | 144:ef7eb2e8f9f7 | 32 | // AACI I2C controller I2C address |
<> | 144:ef7eb2e8f9f7 | 33 | #define AAIC_I2C_ADDR 0x96 |
<> | 144:ef7eb2e8f9f7 | 34 | |
<> | 144:ef7eb2e8f9f7 | 35 | #define TSC_I2C_CID 0x0811 |
<> | 144:ef7eb2e8f9f7 | 36 | |
<> | 144:ef7eb2e8f9f7 | 37 | // TSC I2C controller registers |
<> | 144:ef7eb2e8f9f7 | 38 | #define TSC_I2C_CRID 0x00 |
<> | 144:ef7eb2e8f9f7 | 39 | |
<> | 144:ef7eb2e8f9f7 | 40 | |
<> | 144:ef7eb2e8f9f7 | 41 | // TSSPCPSR Clock prescale register |
<> | 144:ef7eb2e8f9f7 | 42 | #define TSSPCPSR_DFLT 0x0002 // Clock prescale (use with SCR) |
<> | 144:ef7eb2e8f9f7 | 43 | |
<> | 144:ef7eb2e8f9f7 | 44 | // TSC defaults |
<> | 144:ef7eb2e8f9f7 | 45 | #define TSC_XOFF 20 // X offset |
<> | 144:ef7eb2e8f9f7 | 46 | #define TSC_YOFF 20 // Y offset |
<> | 144:ef7eb2e8f9f7 | 47 | #define TSC_MAXVAL 37000 // 0x0FFF * 10 with TSC to LCD scaling |
<> | 144:ef7eb2e8f9f7 | 48 | |
<> | 144:ef7eb2e8f9f7 | 49 | #define TSC_TSU 15 // Setup delay 600nS min |
<> | 144:ef7eb2e8f9f7 | 50 | #define AAIC_TSU 25 // Setup delay 1000nS min |
<> | 144:ef7eb2e8f9f7 | 51 | #define SHIELD_TSU 25 // Setup delay 1000nS min |
<> | 144:ef7eb2e8f9f7 | 52 | |
<> | 144:ef7eb2e8f9f7 | 53 | |
<> | 144:ef7eb2e8f9f7 | 54 | static const PinMap PinMap_I2C_SDA[] = { |
<> | 144:ef7eb2e8f9f7 | 55 | {TSC_SDA, I2C_0, 0}, |
<> | 144:ef7eb2e8f9f7 | 56 | {AUD_SDA, I2C_1, 0}, |
<> | 144:ef7eb2e8f9f7 | 57 | {SHIELD_0_SDA, I2C_2, 0}, |
<> | 144:ef7eb2e8f9f7 | 58 | {SHIELD_1_SDA, I2C_3, 0}, |
<> | 144:ef7eb2e8f9f7 | 59 | {NC , NC , 0} |
<> | 144:ef7eb2e8f9f7 | 60 | }; |
<> | 144:ef7eb2e8f9f7 | 61 | |
<> | 144:ef7eb2e8f9f7 | 62 | static const PinMap PinMap_I2C_SCL[] = { |
<> | 144:ef7eb2e8f9f7 | 63 | {TSC_SCL, I2C_0, 0}, |
<> | 144:ef7eb2e8f9f7 | 64 | {AUD_SCL, I2C_1, 0}, |
<> | 144:ef7eb2e8f9f7 | 65 | {SHIELD_0_SCL, I2C_2, 0}, |
<> | 144:ef7eb2e8f9f7 | 66 | {SHIELD_1_SCL, I2C_3, 0}, |
<> | 144:ef7eb2e8f9f7 | 67 | {NC , NC, 0} |
<> | 144:ef7eb2e8f9f7 | 68 | }; |
<> | 144:ef7eb2e8f9f7 | 69 | |
<> | 144:ef7eb2e8f9f7 | 70 | static inline void i2c_send_byte(i2c_t *obj, unsigned char c) |
<> | 144:ef7eb2e8f9f7 | 71 | { |
<> | 144:ef7eb2e8f9f7 | 72 | int loop; |
<> | 144:ef7eb2e8f9f7 | 73 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 74 | case I2C_0: |
<> | 144:ef7eb2e8f9f7 | 75 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 76 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 77 | |
<> | 144:ef7eb2e8f9f7 | 78 | for (loop = 0; loop < 8; loop++) |
<> | 144:ef7eb2e8f9f7 | 79 | { |
<> | 144:ef7eb2e8f9f7 | 80 | if (c & (1 << (7 - loop))) |
<> | 144:ef7eb2e8f9f7 | 81 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 82 | else |
<> | 144:ef7eb2e8f9f7 | 83 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 84 | |
<> | 144:ef7eb2e8f9f7 | 85 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 86 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 87 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 88 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 89 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 90 | } |
<> | 144:ef7eb2e8f9f7 | 91 | |
<> | 144:ef7eb2e8f9f7 | 92 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 93 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 94 | break; |
<> | 144:ef7eb2e8f9f7 | 95 | case I2C_1: |
<> | 144:ef7eb2e8f9f7 | 96 | for (loop = 0; loop < 8; loop++) { |
<> | 144:ef7eb2e8f9f7 | 97 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 98 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 99 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 100 | if (c & (1 << (7 - loop))) |
<> | 144:ef7eb2e8f9f7 | 101 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 102 | else |
<> | 144:ef7eb2e8f9f7 | 103 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 104 | |
<> | 144:ef7eb2e8f9f7 | 105 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 106 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 107 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 108 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 109 | } |
<> | 144:ef7eb2e8f9f7 | 110 | |
<> | 144:ef7eb2e8f9f7 | 111 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 112 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 113 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 114 | break; |
<> | 144:ef7eb2e8f9f7 | 115 | case I2C_2: |
<> | 144:ef7eb2e8f9f7 | 116 | case I2C_3: |
<> | 144:ef7eb2e8f9f7 | 117 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 118 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 119 | |
<> | 144:ef7eb2e8f9f7 | 120 | for (loop = 0; loop < 8; loop++) |
<> | 144:ef7eb2e8f9f7 | 121 | { |
<> | 144:ef7eb2e8f9f7 | 122 | if (c & (1 << (7 - loop))) |
<> | 144:ef7eb2e8f9f7 | 123 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 124 | else |
<> | 144:ef7eb2e8f9f7 | 125 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 126 | |
<> | 144:ef7eb2e8f9f7 | 127 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 128 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 129 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 130 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 131 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 132 | } |
<> | 144:ef7eb2e8f9f7 | 133 | |
<> | 144:ef7eb2e8f9f7 | 134 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 135 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 136 | break; |
<> | 144:ef7eb2e8f9f7 | 137 | } |
<> | 144:ef7eb2e8f9f7 | 138 | } |
<> | 144:ef7eb2e8f9f7 | 139 | |
<> | 144:ef7eb2e8f9f7 | 140 | static inline unsigned char i2c_receive_byte(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 141 | { |
<> | 144:ef7eb2e8f9f7 | 142 | int data_receive_byte, loop; |
<> | 144:ef7eb2e8f9f7 | 143 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 144 | case I2C_0: |
<> | 144:ef7eb2e8f9f7 | 145 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 146 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 147 | |
<> | 144:ef7eb2e8f9f7 | 148 | data_receive_byte = 0; |
<> | 144:ef7eb2e8f9f7 | 149 | |
<> | 144:ef7eb2e8f9f7 | 150 | for (loop = 0; loop < 8; loop++) |
<> | 144:ef7eb2e8f9f7 | 151 | { |
<> | 144:ef7eb2e8f9f7 | 152 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 153 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 154 | if ((obj->i2c->CONTROL & SDA)) |
<> | 144:ef7eb2e8f9f7 | 155 | data_receive_byte += (1 << (7 - loop)); |
<> | 144:ef7eb2e8f9f7 | 156 | |
<> | 144:ef7eb2e8f9f7 | 157 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 158 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 159 | } |
<> | 144:ef7eb2e8f9f7 | 160 | |
<> | 144:ef7eb2e8f9f7 | 161 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 162 | i2c_delay(TSC_TSU); |
<> | 144:ef7eb2e8f9f7 | 163 | break; |
<> | 144:ef7eb2e8f9f7 | 164 | case I2C_1: |
<> | 144:ef7eb2e8f9f7 | 165 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 166 | data_receive_byte = 0; |
<> | 144:ef7eb2e8f9f7 | 167 | |
<> | 144:ef7eb2e8f9f7 | 168 | for (loop = 0; loop < 8; loop++) { |
<> | 144:ef7eb2e8f9f7 | 169 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 170 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 171 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 172 | obj->i2c->CONTROLS = SCL | SDA; |
<> | 144:ef7eb2e8f9f7 | 173 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 174 | if ((obj->i2c->CONTROL & SDA)) |
<> | 144:ef7eb2e8f9f7 | 175 | data_receive_byte += (1 << (7 - loop)); |
<> | 144:ef7eb2e8f9f7 | 176 | |
<> | 144:ef7eb2e8f9f7 | 177 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 178 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 179 | } |
<> | 144:ef7eb2e8f9f7 | 180 | |
<> | 144:ef7eb2e8f9f7 | 181 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 182 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 183 | i2c_delay(AAIC_TSU); |
<> | 144:ef7eb2e8f9f7 | 184 | break; |
<> | 144:ef7eb2e8f9f7 | 185 | case I2C_2: |
<> | 144:ef7eb2e8f9f7 | 186 | case I2C_3: |
<> | 144:ef7eb2e8f9f7 | 187 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 188 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 189 | |
<> | 144:ef7eb2e8f9f7 | 190 | data_receive_byte = 0; |
<> | 144:ef7eb2e8f9f7 | 191 | |
<> | 144:ef7eb2e8f9f7 | 192 | for (loop = 0; loop < 8; loop++) |
<> | 144:ef7eb2e8f9f7 | 193 | { |
<> | 144:ef7eb2e8f9f7 | 194 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 195 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 196 | if ((obj->i2c->CONTROL & SDA)) |
<> | 144:ef7eb2e8f9f7 | 197 | data_receive_byte += (1 << (7 - loop)); |
<> | 144:ef7eb2e8f9f7 | 198 | |
<> | 144:ef7eb2e8f9f7 | 199 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 200 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 201 | } |
<> | 144:ef7eb2e8f9f7 | 202 | |
<> | 144:ef7eb2e8f9f7 | 203 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 204 | i2c_delay(SHIELD_TSU); |
<> | 144:ef7eb2e8f9f7 | 205 | break; |
<> | 144:ef7eb2e8f9f7 | 206 | } |
<> | 144:ef7eb2e8f9f7 | 207 | return data_receive_byte; |
<> | 144:ef7eb2e8f9f7 | 208 | } |
<> | 144:ef7eb2e8f9f7 | 209 | |
<> | 144:ef7eb2e8f9f7 | 210 | static inline int i2c_receive_ack(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 211 | { |
<> | 144:ef7eb2e8f9f7 | 212 | int nack; |
<> | 144:ef7eb2e8f9f7 | 213 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 214 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 215 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 216 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 217 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 218 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 219 | } |
<> | 144:ef7eb2e8f9f7 | 220 | |
<> | 144:ef7eb2e8f9f7 | 221 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 222 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 223 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 224 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 225 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 226 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 227 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 228 | nack = obj->i2c->CONTROL & SDA; |
<> | 144:ef7eb2e8f9f7 | 229 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 230 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 231 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 232 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 233 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 234 | if(nack==0) |
<> | 144:ef7eb2e8f9f7 | 235 | return 1; |
<> | 144:ef7eb2e8f9f7 | 236 | |
<> | 144:ef7eb2e8f9f7 | 237 | return 0; |
<> | 144:ef7eb2e8f9f7 | 238 | } |
<> | 144:ef7eb2e8f9f7 | 239 | |
<> | 144:ef7eb2e8f9f7 | 240 | |
<> | 144:ef7eb2e8f9f7 | 241 | static inline void i2c_send_nack(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 242 | { |
<> | 144:ef7eb2e8f9f7 | 243 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 244 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 245 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 246 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 247 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 248 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 249 | } |
<> | 144:ef7eb2e8f9f7 | 250 | |
<> | 144:ef7eb2e8f9f7 | 251 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 252 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 253 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 254 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 255 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 256 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 257 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 258 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 259 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 260 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 261 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 262 | |
<> | 144:ef7eb2e8f9f7 | 263 | } |
<> | 144:ef7eb2e8f9f7 | 264 | |
<> | 144:ef7eb2e8f9f7 | 265 | static inline void i2c_send_ack(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 266 | { |
<> | 144:ef7eb2e8f9f7 | 267 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 268 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 269 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 270 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 271 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 272 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 273 | } |
<> | 144:ef7eb2e8f9f7 | 274 | |
<> | 144:ef7eb2e8f9f7 | 275 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 276 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 277 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 278 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 279 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 280 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 281 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 282 | |
<> | 144:ef7eb2e8f9f7 | 283 | } |
<> | 144:ef7eb2e8f9f7 | 284 | |
<> | 144:ef7eb2e8f9f7 | 285 | void i2c_init(i2c_t *obj, PinName sda, PinName scl) |
<> | 144:ef7eb2e8f9f7 | 286 | { |
<> | 144:ef7eb2e8f9f7 | 287 | // determine the SPI to use |
<> | 144:ef7eb2e8f9f7 | 288 | I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); |
<> | 144:ef7eb2e8f9f7 | 289 | I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); |
<> | 144:ef7eb2e8f9f7 | 290 | obj->i2c = (MPS2_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); |
<> | 144:ef7eb2e8f9f7 | 291 | |
<> | 144:ef7eb2e8f9f7 | 292 | if ((int)obj->i2c == NC) { |
<> | 144:ef7eb2e8f9f7 | 293 | error("I2C pin mapping failed"); |
<> | 144:ef7eb2e8f9f7 | 294 | } |
<> | 144:ef7eb2e8f9f7 | 295 | |
<> | 144:ef7eb2e8f9f7 | 296 | pinmap_pinout(sda, PinMap_I2C_SDA); |
<> | 144:ef7eb2e8f9f7 | 297 | pinmap_pinout(scl, PinMap_I2C_SCL); |
<> | 144:ef7eb2e8f9f7 | 298 | |
<> | 144:ef7eb2e8f9f7 | 299 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 300 | case I2C_2: CMSDK_GPIO0->ALTFUNCSET |= 0x8020; break; |
<> | 144:ef7eb2e8f9f7 | 301 | case I2C_3: CMSDK_GPIO1->ALTFUNCSET |= 0x8000; |
<> | 144:ef7eb2e8f9f7 | 302 | CMSDK_GPIO2->ALTFUNCSET |= 0x0200; break; |
<> | 144:ef7eb2e8f9f7 | 303 | } |
<> | 144:ef7eb2e8f9f7 | 304 | |
<> | 144:ef7eb2e8f9f7 | 305 | |
<> | 144:ef7eb2e8f9f7 | 306 | } |
<> | 144:ef7eb2e8f9f7 | 307 | |
<> | 144:ef7eb2e8f9f7 | 308 | int i2c_start(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 309 | { |
<> | 144:ef7eb2e8f9f7 | 310 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 311 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 312 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 313 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 314 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 315 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 316 | } |
<> | 144:ef7eb2e8f9f7 | 317 | |
<> | 144:ef7eb2e8f9f7 | 318 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 319 | obj->i2c->CONTROLS = SDA | SCL; |
<> | 144:ef7eb2e8f9f7 | 320 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 321 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 322 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 323 | |
<> | 144:ef7eb2e8f9f7 | 324 | return 0; |
<> | 144:ef7eb2e8f9f7 | 325 | } |
<> | 144:ef7eb2e8f9f7 | 326 | |
<> | 144:ef7eb2e8f9f7 | 327 | int i2c_start_tsc(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 328 | { |
<> | 144:ef7eb2e8f9f7 | 329 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 330 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 331 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 332 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 333 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 334 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 335 | } |
<> | 144:ef7eb2e8f9f7 | 336 | |
<> | 144:ef7eb2e8f9f7 | 337 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 338 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 339 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 340 | obj->i2c->CONTROLC = SCL; |
<> | 144:ef7eb2e8f9f7 | 341 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 342 | |
<> | 144:ef7eb2e8f9f7 | 343 | return 0; |
<> | 144:ef7eb2e8f9f7 | 344 | } |
<> | 144:ef7eb2e8f9f7 | 345 | |
<> | 144:ef7eb2e8f9f7 | 346 | int i2c_stop(i2c_t *obj) |
<> | 144:ef7eb2e8f9f7 | 347 | { |
<> | 144:ef7eb2e8f9f7 | 348 | int delay_value; |
<> | 144:ef7eb2e8f9f7 | 349 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 350 | case I2C_0: delay_value = TSC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 351 | case I2C_1: delay_value = AAIC_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 352 | case I2C_2: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 353 | case I2C_3: delay_value = SHIELD_TSU; break; |
<> | 144:ef7eb2e8f9f7 | 354 | } |
<> | 144:ef7eb2e8f9f7 | 355 | // Actual stop bit |
<> | 144:ef7eb2e8f9f7 | 356 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 357 | obj->i2c->CONTROLC = SDA; |
<> | 144:ef7eb2e8f9f7 | 358 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 359 | obj->i2c->CONTROLS = SCL; |
<> | 144:ef7eb2e8f9f7 | 360 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 361 | obj->i2c->CONTROLS = SDA; |
<> | 144:ef7eb2e8f9f7 | 362 | i2c_delay(delay_value); |
<> | 144:ef7eb2e8f9f7 | 363 | |
<> | 144:ef7eb2e8f9f7 | 364 | return 0; |
<> | 144:ef7eb2e8f9f7 | 365 | } |
<> | 144:ef7eb2e8f9f7 | 366 | |
<> | 144:ef7eb2e8f9f7 | 367 | |
<> | 144:ef7eb2e8f9f7 | 368 | |
<> | 144:ef7eb2e8f9f7 | 369 | void i2c_frequency(i2c_t *obj, int hz) { |
<> | 144:ef7eb2e8f9f7 | 370 | } |
<> | 144:ef7eb2e8f9f7 | 371 | |
<> | 144:ef7eb2e8f9f7 | 372 | int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) |
<> | 144:ef7eb2e8f9f7 | 373 | { |
<> | 144:ef7eb2e8f9f7 | 374 | unsigned int loop, rxdata; |
<> | 144:ef7eb2e8f9f7 | 375 | int sadr, ack, bytes_read; |
<> | 144:ef7eb2e8f9f7 | 376 | rxdata=0; |
<> | 144:ef7eb2e8f9f7 | 377 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 378 | case I2C_0: |
<> | 144:ef7eb2e8f9f7 | 379 | sadr = TSC_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 380 | break; |
<> | 144:ef7eb2e8f9f7 | 381 | case I2C_1: |
<> | 144:ef7eb2e8f9f7 | 382 | sadr = AAIC_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 383 | break; |
<> | 144:ef7eb2e8f9f7 | 384 | case I2C_2: |
<> | 144:ef7eb2e8f9f7 | 385 | case I2C_3: |
<> | 144:ef7eb2e8f9f7 | 386 | sadr = address; //LM75_I2C_ADDR; or MMA7660_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 387 | break; |
<> | 144:ef7eb2e8f9f7 | 388 | } |
<> | 144:ef7eb2e8f9f7 | 389 | bytes_read = 0; |
<> | 144:ef7eb2e8f9f7 | 390 | // Start bit |
<> | 144:ef7eb2e8f9f7 | 391 | i2c_start(obj); |
<> | 144:ef7eb2e8f9f7 | 392 | |
<> | 144:ef7eb2e8f9f7 | 393 | switch ((int)obj->i2c) { |
<> | 144:ef7eb2e8f9f7 | 394 | case I2C_0: |
<> | 144:ef7eb2e8f9f7 | 395 | // Set serial and register address |
<> | 144:ef7eb2e8f9f7 | 396 | i2c_send_byte(obj,sadr); |
<> | 144:ef7eb2e8f9f7 | 397 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 398 | i2c_send_byte(obj, address); |
<> | 144:ef7eb2e8f9f7 | 399 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 400 | |
<> | 144:ef7eb2e8f9f7 | 401 | // Stop bit |
<> | 144:ef7eb2e8f9f7 | 402 | i2c_stop(obj); |
<> | 144:ef7eb2e8f9f7 | 403 | |
<> | 144:ef7eb2e8f9f7 | 404 | // Start bit |
<> | 144:ef7eb2e8f9f7 | 405 | i2c_start_tsc(obj); |
<> | 144:ef7eb2e8f9f7 | 406 | |
<> | 144:ef7eb2e8f9f7 | 407 | // Read from I2C address |
<> | 144:ef7eb2e8f9f7 | 408 | i2c_send_byte(obj,sadr | 1); |
<> | 144:ef7eb2e8f9f7 | 409 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 410 | |
<> | 144:ef7eb2e8f9f7 | 411 | rxdata = (i2c_receive_byte(obj) & 0xFF); |
<> | 144:ef7eb2e8f9f7 | 412 | data[((length-1)-bytes_read)] = (char)rxdata; |
<> | 144:ef7eb2e8f9f7 | 413 | bytes_read++; |
<> | 144:ef7eb2e8f9f7 | 414 | // Read multiple bytes |
<> | 144:ef7eb2e8f9f7 | 415 | if ((length > 1) && (length < 5)) |
<> | 144:ef7eb2e8f9f7 | 416 | { |
<> | 144:ef7eb2e8f9f7 | 417 | for (loop = 1; loop <= (length - 1); loop++) |
<> | 144:ef7eb2e8f9f7 | 418 | { |
<> | 144:ef7eb2e8f9f7 | 419 | // Send ACK |
<> | 144:ef7eb2e8f9f7 | 420 | i2c_send_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 421 | |
<> | 144:ef7eb2e8f9f7 | 422 | // Next byte |
<> | 144:ef7eb2e8f9f7 | 423 | //rxdata = ((rxdata << 8) & 0xFFFFFF00); |
<> | 144:ef7eb2e8f9f7 | 424 | //rxdata |= (i2c_receive_byte(obj) & 0xFF); |
<> | 144:ef7eb2e8f9f7 | 425 | rxdata = i2c_receive_byte(obj); |
<> | 144:ef7eb2e8f9f7 | 426 | data[(length-1)-bytes_read] = (char)rxdata; |
<> | 144:ef7eb2e8f9f7 | 427 | bytes_read++; |
<> | 144:ef7eb2e8f9f7 | 428 | |
<> | 144:ef7eb2e8f9f7 | 429 | } |
<> | 144:ef7eb2e8f9f7 | 430 | } |
<> | 144:ef7eb2e8f9f7 | 431 | break; |
<> | 144:ef7eb2e8f9f7 | 432 | case I2C_1: |
<> | 144:ef7eb2e8f9f7 | 433 | // Set serial and register address |
<> | 144:ef7eb2e8f9f7 | 434 | i2c_send_byte(obj,sadr); |
<> | 144:ef7eb2e8f9f7 | 435 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 436 | i2c_send_byte(obj, address); |
<> | 144:ef7eb2e8f9f7 | 437 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 438 | |
<> | 144:ef7eb2e8f9f7 | 439 | // Stop bit |
<> | 144:ef7eb2e8f9f7 | 440 | i2c_stop(obj); |
<> | 144:ef7eb2e8f9f7 | 441 | |
<> | 144:ef7eb2e8f9f7 | 442 | // Start bit |
<> | 144:ef7eb2e8f9f7 | 443 | i2c_start_tsc(obj); |
<> | 144:ef7eb2e8f9f7 | 444 | // Fall through to read data |
<> | 144:ef7eb2e8f9f7 | 445 | case I2C_2: |
<> | 144:ef7eb2e8f9f7 | 446 | case I2C_3: |
<> | 144:ef7eb2e8f9f7 | 447 | // Read from preset register address pointer |
<> | 144:ef7eb2e8f9f7 | 448 | i2c_send_byte(obj,sadr | 1); |
<> | 144:ef7eb2e8f9f7 | 449 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 450 | |
<> | 144:ef7eb2e8f9f7 | 451 | rxdata = i2c_receive_byte(obj); |
<> | 144:ef7eb2e8f9f7 | 452 | data[bytes_read] = (char)rxdata; |
<> | 144:ef7eb2e8f9f7 | 453 | bytes_read++; |
<> | 144:ef7eb2e8f9f7 | 454 | // Read multiple bytes |
<> | 144:ef7eb2e8f9f7 | 455 | if ((length > 1) && (length < 5)) |
<> | 144:ef7eb2e8f9f7 | 456 | { |
<> | 144:ef7eb2e8f9f7 | 457 | for (loop = 1; loop <= (length - 1); loop++) |
<> | 144:ef7eb2e8f9f7 | 458 | { |
<> | 144:ef7eb2e8f9f7 | 459 | // Send ACK |
<> | 144:ef7eb2e8f9f7 | 460 | i2c_send_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 461 | |
<> | 144:ef7eb2e8f9f7 | 462 | // Next byte |
<> | 144:ef7eb2e8f9f7 | 463 | rxdata = i2c_receive_byte(obj); |
<> | 144:ef7eb2e8f9f7 | 464 | data[loop] = (char)rxdata; |
<> | 144:ef7eb2e8f9f7 | 465 | bytes_read++; |
<> | 144:ef7eb2e8f9f7 | 466 | |
<> | 144:ef7eb2e8f9f7 | 467 | } |
<> | 144:ef7eb2e8f9f7 | 468 | } |
<> | 144:ef7eb2e8f9f7 | 469 | break; |
<> | 144:ef7eb2e8f9f7 | 470 | } |
<> | 144:ef7eb2e8f9f7 | 471 | i2c_send_nack(obj); |
<> | 144:ef7eb2e8f9f7 | 472 | |
<> | 144:ef7eb2e8f9f7 | 473 | i2c_stop(obj); // Actual stop bit |
<> | 144:ef7eb2e8f9f7 | 474 | |
<> | 144:ef7eb2e8f9f7 | 475 | return bytes_read; |
<> | 144:ef7eb2e8f9f7 | 476 | } |
<> | 144:ef7eb2e8f9f7 | 477 | |
<> | 144:ef7eb2e8f9f7 | 478 | int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) |
<> | 144:ef7eb2e8f9f7 | 479 | { |
<> | 144:ef7eb2e8f9f7 | 480 | int ack=0; |
<> | 144:ef7eb2e8f9f7 | 481 | int sadr; |
<> | 144:ef7eb2e8f9f7 | 482 | char * ptr; |
<> | 144:ef7eb2e8f9f7 | 483 | char addr; |
<> | 144:ef7eb2e8f9f7 | 484 | ptr = (char*)data; |
<> | 144:ef7eb2e8f9f7 | 485 | switch ((int)obj->i2c) |
<> | 144:ef7eb2e8f9f7 | 486 | { |
<> | 144:ef7eb2e8f9f7 | 487 | case I2C_0: |
<> | 144:ef7eb2e8f9f7 | 488 | sadr = TSC_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 489 | addr = address; |
<> | 144:ef7eb2e8f9f7 | 490 | break; |
<> | 144:ef7eb2e8f9f7 | 491 | case I2C_1: |
<> | 144:ef7eb2e8f9f7 | 492 | sadr = AAIC_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 493 | addr = address; |
<> | 144:ef7eb2e8f9f7 | 494 | break; |
<> | 144:ef7eb2e8f9f7 | 495 | case I2C_2: |
<> | 144:ef7eb2e8f9f7 | 496 | case I2C_3: |
<> | 144:ef7eb2e8f9f7 | 497 | sadr = address; //LM75_I2C_ADDR or MMA7660_I2C_ADDR; |
<> | 144:ef7eb2e8f9f7 | 498 | addr = *ptr++; |
<> | 144:ef7eb2e8f9f7 | 499 | break; |
<> | 144:ef7eb2e8f9f7 | 500 | } |
<> | 144:ef7eb2e8f9f7 | 501 | |
<> | 144:ef7eb2e8f9f7 | 502 | // printf("adr = %x, reg = %x\n",sadr, address); |
<> | 144:ef7eb2e8f9f7 | 503 | i2c_start(obj); |
<> | 144:ef7eb2e8f9f7 | 504 | |
<> | 144:ef7eb2e8f9f7 | 505 | // Set serial and register address |
<> | 144:ef7eb2e8f9f7 | 506 | i2c_send_byte(obj,sadr); |
<> | 144:ef7eb2e8f9f7 | 507 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 508 | i2c_send_byte(obj, addr); |
<> | 144:ef7eb2e8f9f7 | 509 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 510 | |
<> | 144:ef7eb2e8f9f7 | 511 | for(int i = 1; i<length; i++) |
<> | 144:ef7eb2e8f9f7 | 512 | { |
<> | 144:ef7eb2e8f9f7 | 513 | i2c_send_byte(obj, *ptr++); |
<> | 144:ef7eb2e8f9f7 | 514 | ack += i2c_receive_ack(obj); |
<> | 144:ef7eb2e8f9f7 | 515 | } |
<> | 144:ef7eb2e8f9f7 | 516 | |
<> | 144:ef7eb2e8f9f7 | 517 | i2c_stop(obj); |
<> | 144:ef7eb2e8f9f7 | 518 | if(ack==3) { return 1; } |
<> | 144:ef7eb2e8f9f7 | 519 | else{ return 0; } |
<> | 144:ef7eb2e8f9f7 | 520 | |
<> | 144:ef7eb2e8f9f7 | 521 | } |
<> | 144:ef7eb2e8f9f7 | 522 | |
<> | 144:ef7eb2e8f9f7 | 523 | void i2c_reset(i2c_t *obj) { |
<> | 144:ef7eb2e8f9f7 | 524 | i2c_stop(obj); |
<> | 144:ef7eb2e8f9f7 | 525 | } |
<> | 144:ef7eb2e8f9f7 | 526 | |
<> | 144:ef7eb2e8f9f7 | 527 | int i2c_byte_read(i2c_t *obj, int last) { |
<> | 144:ef7eb2e8f9f7 | 528 | return 0; |
<> | 144:ef7eb2e8f9f7 | 529 | } |
<> | 144:ef7eb2e8f9f7 | 530 | |
<> | 144:ef7eb2e8f9f7 | 531 | int i2c_byte_write(i2c_t *obj, int data) { |
<> | 144:ef7eb2e8f9f7 | 532 | return 0; |
<> | 144:ef7eb2e8f9f7 | 533 | } |