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-src by
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c@427:8eeb5157dee4, 2014-12-04 (annotated)
- Committer:
- mbed_official
- Date:
- Thu Dec 04 07:30:08 2014 +0000
- Revision:
- 427:8eeb5157dee4
- Parent:
- 422:a032ac66f24e
- Child:
- 430:d406b7919023
Synchronized with git revision e815194b578628edb5746650abfdde926be5e3fe
Full URL: https://github.com/mbedmicro/mbed/commit/e815194b578628edb5746650abfdde926be5e3fe/
Targets: RZ_A1H - Fix bugs that I2C freq become fixed 100kHz and a static value will be indefiniteness.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mbed_official | 390:35c2c1cf29cd | 1 | /* mbed Microcontroller Library |
| mbed_official | 390:35c2c1cf29cd | 2 | * Copyright (c) 2006-2013 ARM Limited |
| mbed_official | 390:35c2c1cf29cd | 3 | * |
| mbed_official | 390:35c2c1cf29cd | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| mbed_official | 390:35c2c1cf29cd | 5 | * you may not use this file except in compliance with the License. |
| mbed_official | 390:35c2c1cf29cd | 6 | * You may obtain a copy of the License at |
| mbed_official | 390:35c2c1cf29cd | 7 | * |
| mbed_official | 390:35c2c1cf29cd | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| mbed_official | 390:35c2c1cf29cd | 9 | * |
| mbed_official | 390:35c2c1cf29cd | 10 | * Unless required by applicable law or agreed to in writing, software |
| mbed_official | 390:35c2c1cf29cd | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| mbed_official | 390:35c2c1cf29cd | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| mbed_official | 390:35c2c1cf29cd | 13 | * See the License for the specific language governing permissions and |
| mbed_official | 390:35c2c1cf29cd | 14 | * limitations under the License. |
| mbed_official | 390:35c2c1cf29cd | 15 | */ |
| mbed_official | 390:35c2c1cf29cd | 16 | #include "mbed_assert.h" |
| mbed_official | 390:35c2c1cf29cd | 17 | #include "i2c_api.h" |
| mbed_official | 390:35c2c1cf29cd | 18 | #include "cmsis.h" |
| mbed_official | 390:35c2c1cf29cd | 19 | #include "pinmap.h" |
| mbed_official | 390:35c2c1cf29cd | 20 | |
| mbed_official | 390:35c2c1cf29cd | 21 | |
| mbed_official | 390:35c2c1cf29cd | 22 | #include "riic_iodefine.h" |
| mbed_official | 422:a032ac66f24e | 23 | #include "RZ_A1_Init.h" |
| mbed_official | 422:a032ac66f24e | 24 | #include "MBRZA1H.h" |
| mbed_official | 390:35c2c1cf29cd | 25 | |
| mbed_official | 390:35c2c1cf29cd | 26 | volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST; |
| mbed_official | 390:35c2c1cf29cd | 27 | |
| mbed_official | 390:35c2c1cf29cd | 28 | #define REG(N) \ |
| mbed_official | 390:35c2c1cf29cd | 29 | RIIC[obj->i2c]->RIICn##N |
| mbed_official | 390:35c2c1cf29cd | 30 | |
| mbed_official | 390:35c2c1cf29cd | 31 | #define NACKF (1 << 4) |
| mbed_official | 390:35c2c1cf29cd | 32 | |
| mbed_official | 390:35c2c1cf29cd | 33 | static const PinMap PinMap_I2C_SDA[] = { |
| mbed_official | 390:35c2c1cf29cd | 34 | {P1_1 , I2C_0, 1}, |
| mbed_official | 390:35c2c1cf29cd | 35 | {P1_3 , I2C_1, 1}, |
| mbed_official | 390:35c2c1cf29cd | 36 | {P1_7 , I2C_3, 1}, |
| mbed_official | 390:35c2c1cf29cd | 37 | {NC , NC , 0} |
| mbed_official | 390:35c2c1cf29cd | 38 | }; |
| mbed_official | 390:35c2c1cf29cd | 39 | |
| mbed_official | 390:35c2c1cf29cd | 40 | static const PinMap PinMap_I2C_SCL[] = { |
| mbed_official | 390:35c2c1cf29cd | 41 | {P1_0 , I2C_0, 1}, |
| mbed_official | 390:35c2c1cf29cd | 42 | {P1_2 , I2C_1, 1}, |
| mbed_official | 390:35c2c1cf29cd | 43 | {P1_6 , I2C_3, 1}, |
| mbed_official | 390:35c2c1cf29cd | 44 | {NC , NC, 0} |
| mbed_official | 390:35c2c1cf29cd | 45 | }; |
| mbed_official | 390:35c2c1cf29cd | 46 | |
| mbed_official | 390:35c2c1cf29cd | 47 | // Clear the Transmit data Empty TDRE |
| mbed_official | 390:35c2c1cf29cd | 48 | static inline int i2c_addressed(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 49 | volatile int sar0 = (REG(SR1.UINT8[0])&1), |
| mbed_official | 390:35c2c1cf29cd | 50 | trs = (REG(CR2.UINT8[0])&0x20) >> 5; |
| mbed_official | 390:35c2c1cf29cd | 51 | return sar0 | (trs <<1); |
| mbed_official | 390:35c2c1cf29cd | 52 | } |
| mbed_official | 390:35c2c1cf29cd | 53 | |
| mbed_official | 390:35c2c1cf29cd | 54 | static inline int i2c_status(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 55 | return REG(SR2.UINT8[0]); |
| mbed_official | 390:35c2c1cf29cd | 56 | } |
| mbed_official | 390:35c2c1cf29cd | 57 | |
| mbed_official | 390:35c2c1cf29cd | 58 | static inline void i2c_clear_TDRE(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 59 | REG(SR2.UINT32) &= ~(1 << 7); |
| mbed_official | 390:35c2c1cf29cd | 60 | } |
| mbed_official | 390:35c2c1cf29cd | 61 | |
| mbed_official | 390:35c2c1cf29cd | 62 | static inline void i2c_wait_RDRF(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 63 | while (!(i2c_status(obj) & (1 << 5))) ; |
| mbed_official | 390:35c2c1cf29cd | 64 | } |
| mbed_official | 390:35c2c1cf29cd | 65 | |
| mbed_official | 409:a95c696104d3 | 66 | static void i2c_reg_reset(i2c_t *obj) { |
| mbed_official | 409:a95c696104d3 | 67 | // full reset |
| mbed_official | 409:a95c696104d3 | 68 | REG(CR1.UINT8[0]) &= ~(1 << 7); // CR1.ICE off |
| mbed_official | 409:a95c696104d3 | 69 | REG(CR1.UINT8[0]) |= (1 << 6); // CR1.IICRST on |
| mbed_official | 409:a95c696104d3 | 70 | REG(CR1.UINT8[0]) |= (1 << 7); // CR1.ICE on |
| mbed_official | 409:a95c696104d3 | 71 | |
| mbed_official | 409:a95c696104d3 | 72 | REG(MR1.UINT8[0]) = 0x08; // P_phi /8 9bit (including Ack) |
| mbed_official | 409:a95c696104d3 | 73 | REG(SER.UINT8[0]) = 0x00; // no slave addr enabled |
| mbed_official | 409:a95c696104d3 | 74 | |
| mbed_official | 427:8eeb5157dee4 | 75 | // set frequency |
| mbed_official | 427:8eeb5157dee4 | 76 | REG(MR1.UINT8[0]) |= obj->pclk_bit; |
| mbed_official | 427:8eeb5157dee4 | 77 | REG(BRL.UINT32) = obj->width; |
| mbed_official | 427:8eeb5157dee4 | 78 | REG(BRH.UINT32) = obj->width; |
| mbed_official | 409:a95c696104d3 | 79 | |
| mbed_official | 409:a95c696104d3 | 80 | REG(MR2.UINT8[0]) = 0x07; |
| mbed_official | 409:a95c696104d3 | 81 | REG(MR3.UINT8[0]) = 0x00; |
| mbed_official | 409:a95c696104d3 | 82 | |
| mbed_official | 409:a95c696104d3 | 83 | REG(FER.UINT8[0]) = 0x72; // SCLE, NFE enabled, TMOT |
| mbed_official | 409:a95c696104d3 | 84 | REG(IER.UINT8[0]) = 0x00; // no interrupt |
| mbed_official | 409:a95c696104d3 | 85 | |
| mbed_official | 409:a95c696104d3 | 86 | REG(CR1.UINT32) &= ~(1 << 6); // CR1.IICRST negate reset |
| mbed_official | 409:a95c696104d3 | 87 | } |
| mbed_official | 409:a95c696104d3 | 88 | |
| mbed_official | 390:35c2c1cf29cd | 89 | // Wait until the Trans Data Empty (TDRE) is set |
| mbed_official | 390:35c2c1cf29cd | 90 | static int i2c_wait_TDRE(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 91 | int timeout = 0; |
| mbed_official | 390:35c2c1cf29cd | 92 | |
| mbed_official | 390:35c2c1cf29cd | 93 | while (!(i2c_status(obj) & (1 << 7))) { |
| mbed_official | 409:a95c696104d3 | 94 | timeout ++; |
| mbed_official | 390:35c2c1cf29cd | 95 | if (timeout > 100000) return -1; |
| mbed_official | 390:35c2c1cf29cd | 96 | } |
| mbed_official | 390:35c2c1cf29cd | 97 | |
| mbed_official | 390:35c2c1cf29cd | 98 | return 0; |
| mbed_official | 390:35c2c1cf29cd | 99 | } |
| mbed_official | 390:35c2c1cf29cd | 100 | |
| mbed_official | 409:a95c696104d3 | 101 | static inline int i2c_wait_TEND(i2c_t *obj) { |
| mbed_official | 409:a95c696104d3 | 102 | int timeout = 0; |
| mbed_official | 409:a95c696104d3 | 103 | |
| mbed_official | 409:a95c696104d3 | 104 | while (!(i2c_status(obj) & (1 << 6))) { |
| mbed_official | 409:a95c696104d3 | 105 | timeout ++; |
| mbed_official | 409:a95c696104d3 | 106 | if (timeout > 100000) return -1; |
| mbed_official | 409:a95c696104d3 | 107 | } |
| mbed_official | 409:a95c696104d3 | 108 | |
| mbed_official | 409:a95c696104d3 | 109 | return 0; |
| mbed_official | 409:a95c696104d3 | 110 | } |
| mbed_official | 409:a95c696104d3 | 111 | |
| mbed_official | 409:a95c696104d3 | 112 | |
| mbed_official | 390:35c2c1cf29cd | 113 | static inline void i2c_power_enable(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 114 | volatile uint8_t dummy; |
| mbed_official | 390:35c2c1cf29cd | 115 | switch ((int)obj->i2c) { |
| mbed_official | 390:35c2c1cf29cd | 116 | case I2C_0: CPGSTBCR9 &= ~(0x80); break; |
| mbed_official | 390:35c2c1cf29cd | 117 | case I2C_1: CPGSTBCR9 &= ~(0x40); break; |
| mbed_official | 390:35c2c1cf29cd | 118 | case I2C_2: CPGSTBCR9 &= ~(0x20); break; |
| mbed_official | 390:35c2c1cf29cd | 119 | case I2C_3: CPGSTBCR9 &= ~(0x10); break; |
| mbed_official | 390:35c2c1cf29cd | 120 | } |
| mbed_official | 390:35c2c1cf29cd | 121 | dummy = CPGSTBCR9; |
| mbed_official | 390:35c2c1cf29cd | 122 | } |
| mbed_official | 390:35c2c1cf29cd | 123 | |
| mbed_official | 390:35c2c1cf29cd | 124 | void i2c_init(i2c_t *obj, PinName sda, PinName scl) { |
| mbed_official | 390:35c2c1cf29cd | 125 | // determine the SPI to use |
| mbed_official | 390:35c2c1cf29cd | 126 | I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); |
| mbed_official | 390:35c2c1cf29cd | 127 | I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); |
| mbed_official | 390:35c2c1cf29cd | 128 | obj->i2c = pinmap_merge(i2c_sda, i2c_scl); |
| mbed_official | 390:35c2c1cf29cd | 129 | obj->dummy = 1; |
| mbed_official | 390:35c2c1cf29cd | 130 | MBED_ASSERT((int)obj->i2c != NC); |
| mbed_official | 409:a95c696104d3 | 131 | |
| mbed_official | 390:35c2c1cf29cd | 132 | // enable power |
| mbed_official | 390:35c2c1cf29cd | 133 | i2c_power_enable(obj); |
| mbed_official | 390:35c2c1cf29cd | 134 | |
| mbed_official | 427:8eeb5157dee4 | 135 | // set default frequency at 100k |
| mbed_official | 427:8eeb5157dee4 | 136 | i2c_frequency(obj, 100000); |
| mbed_official | 427:8eeb5157dee4 | 137 | |
| mbed_official | 409:a95c696104d3 | 138 | // full reset |
| mbed_official | 409:a95c696104d3 | 139 | i2c_reg_reset(obj); |
| mbed_official | 390:35c2c1cf29cd | 140 | |
| mbed_official | 390:35c2c1cf29cd | 141 | pinmap_pinout(sda, PinMap_I2C_SDA); |
| mbed_official | 390:35c2c1cf29cd | 142 | pinmap_pinout(scl, PinMap_I2C_SCL); |
| mbed_official | 390:35c2c1cf29cd | 143 | } |
| mbed_official | 390:35c2c1cf29cd | 144 | |
| mbed_official | 390:35c2c1cf29cd | 145 | inline int i2c_start(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 146 | if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check |
| mbed_official | 390:35c2c1cf29cd | 147 | return 0xff; |
| mbed_official | 390:35c2c1cf29cd | 148 | } |
| mbed_official | 390:35c2c1cf29cd | 149 | REG(CR2.UINT8[0]) |= 0x62; // start |
| mbed_official | 390:35c2c1cf29cd | 150 | |
| mbed_official | 390:35c2c1cf29cd | 151 | return 0x10; |
| mbed_official | 390:35c2c1cf29cd | 152 | } |
| mbed_official | 390:35c2c1cf29cd | 153 | |
| mbed_official | 390:35c2c1cf29cd | 154 | inline int i2c_stop(i2c_t *obj) { |
| mbed_official | 409:a95c696104d3 | 155 | volatile int timeout = 0; |
| mbed_official | 390:35c2c1cf29cd | 156 | |
| mbed_official | 390:35c2c1cf29cd | 157 | // write the stop bit |
| mbed_official | 390:35c2c1cf29cd | 158 | REG(CR2.UINT32) |= (1 << 3); |
| mbed_official | 409:a95c696104d3 | 159 | |
| mbed_official | 390:35c2c1cf29cd | 160 | // wait for SP bit to reset |
| mbed_official | 390:35c2c1cf29cd | 161 | while(REG(CR2.UINT32) & (1 << 3)) { |
| mbed_official | 390:35c2c1cf29cd | 162 | timeout ++; |
| mbed_official | 390:35c2c1cf29cd | 163 | if (timeout > 100000) return 1; |
| mbed_official | 390:35c2c1cf29cd | 164 | } |
| mbed_official | 390:35c2c1cf29cd | 165 | |
| mbed_official | 390:35c2c1cf29cd | 166 | obj->dummy = 1; |
| mbed_official | 390:35c2c1cf29cd | 167 | REG(CR2.UINT32) &= ~ (1 << 3); |
| mbed_official | 390:35c2c1cf29cd | 168 | return 0; |
| mbed_official | 390:35c2c1cf29cd | 169 | } |
| mbed_official | 390:35c2c1cf29cd | 170 | |
| mbed_official | 390:35c2c1cf29cd | 171 | static inline int i2c_do_write(i2c_t *obj, int value) { |
| mbed_official | 390:35c2c1cf29cd | 172 | // write the data |
| mbed_official | 390:35c2c1cf29cd | 173 | if (!(i2c_status(obj) & NACKF)) { // NACF=0 |
| mbed_official | 390:35c2c1cf29cd | 174 | i2c_wait_TDRE(obj); |
| mbed_official | 390:35c2c1cf29cd | 175 | REG(DRT.UINT32) = value; |
| mbed_official | 390:35c2c1cf29cd | 176 | } else { |
| mbed_official | 390:35c2c1cf29cd | 177 | return 0xff; |
| mbed_official | 390:35c2c1cf29cd | 178 | } |
| mbed_official | 390:35c2c1cf29cd | 179 | return i2c_status(obj); |
| mbed_official | 390:35c2c1cf29cd | 180 | } |
| mbed_official | 390:35c2c1cf29cd | 181 | |
| mbed_official | 390:35c2c1cf29cd | 182 | static inline int i2c_do_read(i2c_t *obj, int last) { |
| mbed_official | 390:35c2c1cf29cd | 183 | if (obj->dummy) { |
| mbed_official | 390:35c2c1cf29cd | 184 | volatile int dummy = REG(DRR.UINT32); |
| mbed_official | 390:35c2c1cf29cd | 185 | obj->dummy = 0; |
| mbed_official | 390:35c2c1cf29cd | 186 | } |
| mbed_official | 409:a95c696104d3 | 187 | |
| mbed_official | 409:a95c696104d3 | 188 | // wait for it to arrive |
| mbed_official | 409:a95c696104d3 | 189 | i2c_wait_RDRF(obj); |
| mbed_official | 409:a95c696104d3 | 190 | |
| mbed_official | 409:a95c696104d3 | 191 | if (last == 2) { |
| mbed_official | 409:a95c696104d3 | 192 | /* this time is befor last byte read */ |
| mbed_official | 409:a95c696104d3 | 193 | /* Set MR3 WATI bit is 1 */; |
| mbed_official | 409:a95c696104d3 | 194 | REG(MR3.UINT32) |= (1 << 6); |
| mbed_official | 409:a95c696104d3 | 195 | } else if (last == 1) { |
| mbed_official | 390:35c2c1cf29cd | 196 | // send a NOT ACK |
| mbed_official | 409:a95c696104d3 | 197 | REG(MR3.UINT32) |= (1 <<3); |
| mbed_official | 390:35c2c1cf29cd | 198 | } else { |
| mbed_official | 390:35c2c1cf29cd | 199 | // send a ACK |
| mbed_official | 409:a95c696104d3 | 200 | REG(MR3.UINT32) &= ~(1 <<3); |
| mbed_official | 390:35c2c1cf29cd | 201 | } |
| mbed_official | 409:a95c696104d3 | 202 | |
| mbed_official | 390:35c2c1cf29cd | 203 | // return the data |
| mbed_official | 390:35c2c1cf29cd | 204 | return (REG(DRR.UINT32) & 0xFF); |
| mbed_official | 390:35c2c1cf29cd | 205 | } |
| mbed_official | 390:35c2c1cf29cd | 206 | |
| mbed_official | 390:35c2c1cf29cd | 207 | void i2c_frequency(i2c_t *obj, int hz) { |
| mbed_official | 422:a032ac66f24e | 208 | int freq; |
| mbed_official | 422:a032ac66f24e | 209 | int oldfreq = 0; |
| mbed_official | 422:a032ac66f24e | 210 | int newfreq = 0; |
| mbed_official | 422:a032ac66f24e | 211 | uint32_t pclk; |
| mbed_official | 422:a032ac66f24e | 212 | uint32_t pclk_base; |
| mbed_official | 422:a032ac66f24e | 213 | uint32_t tmp_width; |
| mbed_official | 422:a032ac66f24e | 214 | uint32_t width = 0; |
| mbed_official | 422:a032ac66f24e | 215 | uint8_t count; |
| mbed_official | 422:a032ac66f24e | 216 | uint8_t pclk_bit = 0; |
| mbed_official | 427:8eeb5157dee4 | 217 | |
| mbed_official | 422:a032ac66f24e | 218 | /* set PCLK */ |
| mbed_official | 427:8eeb5157dee4 | 219 | if (false == RZ_A1_IsClockMode0()) { |
| mbed_official | 422:a032ac66f24e | 220 | pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK; |
| mbed_official | 422:a032ac66f24e | 221 | } else { |
| mbed_official | 422:a032ac66f24e | 222 | pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK; |
| mbed_official | 422:a032ac66f24e | 223 | } |
| mbed_official | 427:8eeb5157dee4 | 224 | |
| mbed_official | 422:a032ac66f24e | 225 | /* Min 10kHz, Max 400kHz */ |
| mbed_official | 422:a032ac66f24e | 226 | if (hz < 10000) { |
| mbed_official | 422:a032ac66f24e | 227 | freq = 10000; |
| mbed_official | 422:a032ac66f24e | 228 | } else if (hz > 400000) { |
| mbed_official | 422:a032ac66f24e | 229 | freq = 400000; |
| mbed_official | 422:a032ac66f24e | 230 | } else { |
| mbed_official | 422:a032ac66f24e | 231 | freq = hz; |
| mbed_official | 422:a032ac66f24e | 232 | } |
| mbed_official | 427:8eeb5157dee4 | 233 | |
| mbed_official | 422:a032ac66f24e | 234 | for (count = 0; count < 7; count++) { |
| mbed_official | 422:a032ac66f24e | 235 | // IIC phi = P0 phi / rate |
| mbed_official | 422:a032ac66f24e | 236 | pclk = pclk_base / (2 << count); |
| mbed_official | 422:a032ac66f24e | 237 | // In case of "CLE = 1, NFE = 1, CKS != 000( IIC phi < P0 phi ), nf = 1" |
| mbed_official | 422:a032ac66f24e | 238 | // freq = 1 / {[( BRH + 2 + 1 ) + ( BRL + 2 + 1 )] / pclk } |
| mbed_official | 422:a032ac66f24e | 239 | // BRH is regarded as same value with BRL |
| mbed_official | 422:a032ac66f24e | 240 | // 2( BRH + 3 ) / pclk = 1 / freq |
| mbed_official | 422:a032ac66f24e | 241 | tmp_width = ((pclk / freq) / 2) - 3; |
| mbed_official | 422:a032ac66f24e | 242 | // Carry in a decimal point |
| mbed_official | 422:a032ac66f24e | 243 | tmp_width += 1; |
| mbed_official | 422:a032ac66f24e | 244 | if ((tmp_width >= 0x00000001) && (tmp_width <= 0x0000001F)) { |
| mbed_official | 422:a032ac66f24e | 245 | // Calculate theoretical value, and Choose max value of them |
| mbed_official | 422:a032ac66f24e | 246 | newfreq = pclk / (tmp_width + 3) / 2; |
| mbed_official | 422:a032ac66f24e | 247 | if (newfreq >= oldfreq) { |
| mbed_official | 422:a032ac66f24e | 248 | oldfreq = newfreq; |
| mbed_official | 422:a032ac66f24e | 249 | width = tmp_width; |
| mbed_official | 422:a032ac66f24e | 250 | pclk_bit = (uint8_t)(0x10 * (count + 1)); |
| mbed_official | 422:a032ac66f24e | 251 | } |
| mbed_official | 422:a032ac66f24e | 252 | } |
| mbed_official | 422:a032ac66f24e | 253 | } |
| mbed_official | 409:a95c696104d3 | 254 | |
| mbed_official | 422:a032ac66f24e | 255 | if (width != 0) { |
| mbed_official | 422:a032ac66f24e | 256 | // I2C Rate |
| mbed_official | 427:8eeb5157dee4 | 257 | obj->pclk_bit = pclk_bit; // P_phi / xx |
| mbed_official | 427:8eeb5157dee4 | 258 | obj->width = (width | 0x000000E0); |
| mbed_official | 422:a032ac66f24e | 259 | } else { |
| mbed_official | 422:a032ac66f24e | 260 | // Default |
| mbed_official | 427:8eeb5157dee4 | 261 | obj->pclk_bit = 0x00; // P_phi / 1 |
| mbed_official | 427:8eeb5157dee4 | 262 | obj->width = 0x000000FF; |
| mbed_official | 422:a032ac66f24e | 263 | } |
| mbed_official | 390:35c2c1cf29cd | 264 | } |
| mbed_official | 390:35c2c1cf29cd | 265 | |
| mbed_official | 390:35c2c1cf29cd | 266 | int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { |
| mbed_official | 409:a95c696104d3 | 267 | int count = 0; |
| mbed_official | 409:a95c696104d3 | 268 | int status; |
| mbed_official | 409:a95c696104d3 | 269 | int value; |
| mbed_official | 409:a95c696104d3 | 270 | volatile uint32_t work_reg = 0; |
| mbed_official | 409:a95c696104d3 | 271 | |
| mbed_official | 409:a95c696104d3 | 272 | |
| mbed_official | 409:a95c696104d3 | 273 | // full reset |
| mbed_official | 409:a95c696104d3 | 274 | i2c_reg_reset(obj); |
| mbed_official | 409:a95c696104d3 | 275 | |
| mbed_official | 390:35c2c1cf29cd | 276 | status = i2c_start(obj); |
| mbed_official | 409:a95c696104d3 | 277 | |
| mbed_official | 390:35c2c1cf29cd | 278 | if (status == 0xff) { |
| mbed_official | 390:35c2c1cf29cd | 279 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 280 | return I2C_ERROR_BUS_BUSY; |
| mbed_official | 390:35c2c1cf29cd | 281 | } |
| mbed_official | 409:a95c696104d3 | 282 | |
| mbed_official | 390:35c2c1cf29cd | 283 | status = i2c_do_write(obj, (address | 0x01)); |
| mbed_official | 390:35c2c1cf29cd | 284 | if (status & 0x01) { |
| mbed_official | 390:35c2c1cf29cd | 285 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 286 | return I2C_ERROR_NO_SLAVE; |
| mbed_official | 390:35c2c1cf29cd | 287 | } |
| mbed_official | 409:a95c696104d3 | 288 | |
| mbed_official | 409:a95c696104d3 | 289 | /* wati RDRF */ |
| mbed_official | 409:a95c696104d3 | 290 | i2c_wait_RDRF(obj); |
| mbed_official | 409:a95c696104d3 | 291 | /* check ACK/NACK */ |
| mbed_official | 409:a95c696104d3 | 292 | if ((REG(SR2.UINT32) & (1 << 4) == 1)) { |
| mbed_official | 409:a95c696104d3 | 293 | /* Slave sends NACK */ |
| mbed_official | 409:a95c696104d3 | 294 | i2c_stop(obj); |
| mbed_official | 409:a95c696104d3 | 295 | return I2C_ERROR_NO_SLAVE; |
| mbed_official | 390:35c2c1cf29cd | 296 | } |
| mbed_official | 390:35c2c1cf29cd | 297 | |
| mbed_official | 409:a95c696104d3 | 298 | // Read in all except last byte |
| mbed_official | 409:a95c696104d3 | 299 | if (length > 1) { |
| mbed_official | 409:a95c696104d3 | 300 | for (count = 0; count < (length - 1); count++) { |
| mbed_official | 409:a95c696104d3 | 301 | if (count == (length - 2)) { |
| mbed_official | 409:a95c696104d3 | 302 | value = i2c_do_read(obj, 1); |
| mbed_official | 409:a95c696104d3 | 303 | } else if ((length >= 3) && (count == (length - 3))) { |
| mbed_official | 409:a95c696104d3 | 304 | value = i2c_do_read(obj, 2); |
| mbed_official | 409:a95c696104d3 | 305 | } else { |
| mbed_official | 409:a95c696104d3 | 306 | value = i2c_do_read(obj, 0); |
| mbed_official | 409:a95c696104d3 | 307 | } |
| mbed_official | 409:a95c696104d3 | 308 | status = i2c_status(obj); |
| mbed_official | 409:a95c696104d3 | 309 | if (status & 0x10) { |
| mbed_official | 409:a95c696104d3 | 310 | i2c_stop(obj); |
| mbed_official | 409:a95c696104d3 | 311 | return count; |
| mbed_official | 409:a95c696104d3 | 312 | } |
| mbed_official | 409:a95c696104d3 | 313 | data[count] = (char) value; |
| mbed_official | 409:a95c696104d3 | 314 | } |
| mbed_official | 409:a95c696104d3 | 315 | } |
| mbed_official | 409:a95c696104d3 | 316 | |
| mbed_official | 390:35c2c1cf29cd | 317 | // read in last byte |
| mbed_official | 409:a95c696104d3 | 318 | i2c_wait_RDRF(obj); |
| mbed_official | 409:a95c696104d3 | 319 | /* RIICnSR2.STOP = 0 */ |
| mbed_official | 409:a95c696104d3 | 320 | REG(SR2.UINT32) &= ~(1 << 3); |
| mbed_official | 409:a95c696104d3 | 321 | /* RIICnCR2.SP = 1 */ |
| mbed_official | 409:a95c696104d3 | 322 | REG(CR2.UINT32) |= (1 << 3); |
| mbed_official | 409:a95c696104d3 | 323 | /* RIICnDRR read */ |
| mbed_official | 409:a95c696104d3 | 324 | value = REG(DRR.UINT32) & 0xFF; |
| mbed_official | 409:a95c696104d3 | 325 | /* RIICnMR3.WAIT = 0 */ |
| mbed_official | 409:a95c696104d3 | 326 | REG(MR3.UINT32) &= ~(1 << 6); |
| mbed_official | 409:a95c696104d3 | 327 | /* wait SR2.STOP = 1 */ |
| mbed_official | 409:a95c696104d3 | 328 | while ((work_reg & (1 << 3)) == (1 << 3)) { |
| mbed_official | 409:a95c696104d3 | 329 | work_reg = REG(SR2.UINT32); |
| mbed_official | 409:a95c696104d3 | 330 | } |
| mbed_official | 409:a95c696104d3 | 331 | /* SR2.NACKF = 0 */ |
| mbed_official | 409:a95c696104d3 | 332 | REG(SR2.UINT32) &= ~(1 << 4); |
| mbed_official | 409:a95c696104d3 | 333 | /* SR2.STOP = 0 */ |
| mbed_official | 409:a95c696104d3 | 334 | REG(SR2.UINT32) &= ~(1 << 3); |
| mbed_official | 390:35c2c1cf29cd | 335 | status = i2c_status(obj); |
| mbed_official | 390:35c2c1cf29cd | 336 | if (status & 0x10) { |
| mbed_official | 390:35c2c1cf29cd | 337 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 338 | return length - 1; |
| mbed_official | 390:35c2c1cf29cd | 339 | } |
| mbed_official | 409:a95c696104d3 | 340 | |
| mbed_official | 390:35c2c1cf29cd | 341 | data[count] = (char) value; |
| mbed_official | 409:a95c696104d3 | 342 | |
| mbed_official | 390:35c2c1cf29cd | 343 | // If not repeated start, send stop. |
| mbed_official | 390:35c2c1cf29cd | 344 | if (stop) { |
| mbed_official | 390:35c2c1cf29cd | 345 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 346 | } |
| mbed_official | 409:a95c696104d3 | 347 | |
| mbed_official | 390:35c2c1cf29cd | 348 | return length; |
| mbed_official | 390:35c2c1cf29cd | 349 | } |
| mbed_official | 390:35c2c1cf29cd | 350 | |
| mbed_official | 390:35c2c1cf29cd | 351 | int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { |
| mbed_official | 390:35c2c1cf29cd | 352 | int i, status; |
| mbed_official | 409:a95c696104d3 | 353 | |
| mbed_official | 409:a95c696104d3 | 354 | // full reset |
| mbed_official | 409:a95c696104d3 | 355 | i2c_reg_reset(obj); |
| mbed_official | 409:a95c696104d3 | 356 | |
| mbed_official | 390:35c2c1cf29cd | 357 | status = i2c_start(obj); |
| mbed_official | 409:a95c696104d3 | 358 | |
| mbed_official | 390:35c2c1cf29cd | 359 | if ((status == 0xff)) { |
| mbed_official | 390:35c2c1cf29cd | 360 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 361 | return I2C_ERROR_BUS_BUSY; |
| mbed_official | 390:35c2c1cf29cd | 362 | } |
| mbed_official | 409:a95c696104d3 | 363 | |
| mbed_official | 390:35c2c1cf29cd | 364 | status = i2c_do_write(obj, address); |
| mbed_official | 390:35c2c1cf29cd | 365 | if (status & 0x10) { |
| mbed_official | 390:35c2c1cf29cd | 366 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 367 | return I2C_ERROR_NO_SLAVE; |
| mbed_official | 390:35c2c1cf29cd | 368 | } |
| mbed_official | 409:a95c696104d3 | 369 | |
| mbed_official | 390:35c2c1cf29cd | 370 | for (i=0; i<length; i++) { |
| mbed_official | 390:35c2c1cf29cd | 371 | status = i2c_do_write(obj, data[i]); |
| mbed_official | 390:35c2c1cf29cd | 372 | if(status & 0x10) { |
| mbed_official | 390:35c2c1cf29cd | 373 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 374 | return i; |
| mbed_official | 390:35c2c1cf29cd | 375 | } |
| mbed_official | 390:35c2c1cf29cd | 376 | } |
| mbed_official | 409:a95c696104d3 | 377 | |
| mbed_official | 409:a95c696104d3 | 378 | i2c_wait_TEND(obj); |
| mbed_official | 409:a95c696104d3 | 379 | |
| mbed_official | 390:35c2c1cf29cd | 380 | // If not repeated start, send stop. |
| mbed_official | 390:35c2c1cf29cd | 381 | if (stop) { |
| mbed_official | 390:35c2c1cf29cd | 382 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 383 | } |
| mbed_official | 409:a95c696104d3 | 384 | |
| mbed_official | 390:35c2c1cf29cd | 385 | return length; |
| mbed_official | 390:35c2c1cf29cd | 386 | } |
| mbed_official | 390:35c2c1cf29cd | 387 | |
| mbed_official | 390:35c2c1cf29cd | 388 | void i2c_reset(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 389 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 390 | } |
| mbed_official | 390:35c2c1cf29cd | 391 | |
| mbed_official | 390:35c2c1cf29cd | 392 | int i2c_byte_read(i2c_t *obj, int last) { |
| mbed_official | 390:35c2c1cf29cd | 393 | return (i2c_do_read(obj, last) & 0xFF); |
| mbed_official | 390:35c2c1cf29cd | 394 | } |
| mbed_official | 390:35c2c1cf29cd | 395 | |
| mbed_official | 390:35c2c1cf29cd | 396 | int i2c_byte_write(i2c_t *obj, int data) { |
| mbed_official | 390:35c2c1cf29cd | 397 | int ack; |
| mbed_official | 390:35c2c1cf29cd | 398 | int status = i2c_do_write(obj, (data & 0xFF)); |
| mbed_official | 390:35c2c1cf29cd | 399 | if (status & NACKF) { |
| mbed_official | 390:35c2c1cf29cd | 400 | ack = 0; |
| mbed_official | 390:35c2c1cf29cd | 401 | } else { |
| mbed_official | 390:35c2c1cf29cd | 402 | ack = 1; |
| mbed_official | 390:35c2c1cf29cd | 403 | } |
| mbed_official | 409:a95c696104d3 | 404 | |
| mbed_official | 390:35c2c1cf29cd | 405 | return ack; |
| mbed_official | 390:35c2c1cf29cd | 406 | } |
| mbed_official | 390:35c2c1cf29cd | 407 | |
| mbed_official | 390:35c2c1cf29cd | 408 | void i2c_slave_mode(i2c_t *obj, int enable_slave) { |
| mbed_official | 390:35c2c1cf29cd | 409 | if (enable_slave != 0) { |
| mbed_official | 390:35c2c1cf29cd | 410 | REG(SER.UINT32) = 0x01; // only slave addr 1 is enabled |
| mbed_official | 390:35c2c1cf29cd | 411 | } else { |
| mbed_official | 390:35c2c1cf29cd | 412 | REG(SER.UINT32) = 0x00; // no slave addr enabled |
| mbed_official | 390:35c2c1cf29cd | 413 | } |
| mbed_official | 390:35c2c1cf29cd | 414 | } |
| mbed_official | 390:35c2c1cf29cd | 415 | |
| mbed_official | 390:35c2c1cf29cd | 416 | int i2c_slave_receive(i2c_t *obj) { |
| mbed_official | 390:35c2c1cf29cd | 417 | int status; |
| mbed_official | 390:35c2c1cf29cd | 418 | int retval; |
| mbed_official | 409:a95c696104d3 | 419 | |
| mbed_official | 390:35c2c1cf29cd | 420 | status = i2c_addressed(obj); |
| mbed_official | 390:35c2c1cf29cd | 421 | switch(status) { |
| mbed_official | 390:35c2c1cf29cd | 422 | case 0x3: retval = 1; break; |
| mbed_official | 390:35c2c1cf29cd | 423 | case 0x2: retval = 2; break; |
| mbed_official | 390:35c2c1cf29cd | 424 | case 0x1: retval = 3; break; |
| mbed_official | 390:35c2c1cf29cd | 425 | default : retval = 1; break; |
| mbed_official | 390:35c2c1cf29cd | 426 | } |
| mbed_official | 409:a95c696104d3 | 427 | |
| mbed_official | 390:35c2c1cf29cd | 428 | return(retval); |
| mbed_official | 390:35c2c1cf29cd | 429 | } |
| mbed_official | 390:35c2c1cf29cd | 430 | |
| mbed_official | 390:35c2c1cf29cd | 431 | int i2c_slave_read(i2c_t *obj, char *data, int length) { |
| mbed_official | 390:35c2c1cf29cd | 432 | int count = 0; |
| mbed_official | 390:35c2c1cf29cd | 433 | int status; |
| mbed_official | 390:35c2c1cf29cd | 434 | |
| mbed_official | 390:35c2c1cf29cd | 435 | if (obj->dummy) { |
| mbed_official | 390:35c2c1cf29cd | 436 | volatile int dummy = REG(DRR.UINT32) ; |
| mbed_official | 390:35c2c1cf29cd | 437 | obj->dummy = 0; |
| mbed_official | 390:35c2c1cf29cd | 438 | } |
| mbed_official | 409:a95c696104d3 | 439 | |
| mbed_official | 390:35c2c1cf29cd | 440 | do { |
| mbed_official | 390:35c2c1cf29cd | 441 | i2c_wait_RDRF(obj); |
| mbed_official | 390:35c2c1cf29cd | 442 | status = i2c_status(obj); |
| mbed_official | 390:35c2c1cf29cd | 443 | if(!(status & 0x10)) { |
| mbed_official | 390:35c2c1cf29cd | 444 | data[count] = REG(DRR.UINT32) & 0xFF; |
| mbed_official | 390:35c2c1cf29cd | 445 | } |
| mbed_official | 390:35c2c1cf29cd | 446 | count++; |
| mbed_official | 390:35c2c1cf29cd | 447 | } while ( !(status & 0x10) && (count < length) ); |
| mbed_official | 409:a95c696104d3 | 448 | |
| mbed_official | 390:35c2c1cf29cd | 449 | if(status & 0x10) { |
| mbed_official | 390:35c2c1cf29cd | 450 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 451 | } |
| mbed_official | 409:a95c696104d3 | 452 | |
| mbed_official | 390:35c2c1cf29cd | 453 | //i2c_clear_TDRE(obj); |
| mbed_official | 409:a95c696104d3 | 454 | |
| mbed_official | 390:35c2c1cf29cd | 455 | return count; |
| mbed_official | 390:35c2c1cf29cd | 456 | } |
| mbed_official | 390:35c2c1cf29cd | 457 | |
| mbed_official | 390:35c2c1cf29cd | 458 | int i2c_slave_write(i2c_t *obj, const char *data, int length) { |
| mbed_official | 390:35c2c1cf29cd | 459 | int count = 0; |
| mbed_official | 390:35c2c1cf29cd | 460 | int status; |
| mbed_official | 409:a95c696104d3 | 461 | |
| mbed_official | 390:35c2c1cf29cd | 462 | if(length <= 0) { |
| mbed_official | 390:35c2c1cf29cd | 463 | return(0); |
| mbed_official | 390:35c2c1cf29cd | 464 | } |
| mbed_official | 409:a95c696104d3 | 465 | |
| mbed_official | 390:35c2c1cf29cd | 466 | do { |
| mbed_official | 390:35c2c1cf29cd | 467 | status = i2c_do_write(obj, data[count]); |
| mbed_official | 390:35c2c1cf29cd | 468 | count++; |
| mbed_official | 390:35c2c1cf29cd | 469 | } while ((count < length) && !(status & 0x10)); |
| mbed_official | 409:a95c696104d3 | 470 | |
| mbed_official | 390:35c2c1cf29cd | 471 | if (!(status & 0x10)) { |
| mbed_official | 390:35c2c1cf29cd | 472 | i2c_stop(obj); |
| mbed_official | 390:35c2c1cf29cd | 473 | } |
| mbed_official | 409:a95c696104d3 | 474 | |
| mbed_official | 390:35c2c1cf29cd | 475 | i2c_clear_TDRE(obj); |
| mbed_official | 409:a95c696104d3 | 476 | |
| mbed_official | 390:35c2c1cf29cd | 477 | return(count); |
| mbed_official | 390:35c2c1cf29cd | 478 | } |
| mbed_official | 390:35c2c1cf29cd | 479 | |
| mbed_official | 390:35c2c1cf29cd | 480 | void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { |
| mbed_official | 390:35c2c1cf29cd | 481 | REG(SAR0.UINT32) = address & 0xfe; |
| mbed_official | 390:35c2c1cf29cd | 482 | } |
