]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/i2c_api.c
1 /* mbed Microcontroller Library
2 * Copyright (c) 2006-2013 ARM Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "mbed_assert.h"
21 #include "clk_freqs.h"
22 #include "PeripheralPins.h"
24 static const uint16_t ICR
[0x40] = {
30 96, 112, 128, 144, 160,
31 192, 240, 160, 192, 224,
32 256, 288, 320, 384, 480,
33 320, 384, 448, 512, 576,
34 640, 768, 960, 640, 768,
35 896, 1024, 1152, 1280, 1536,
36 1920, 1280, 1536, 1792, 2048,
37 2304, 2560, 3072, 3840
41 void i2c_init(i2c_t
*obj
, PinName sda
, PinName scl
) {
42 // determine the I2C to use
43 I2CName i2c_sda
= (I2CName
)pinmap_peripheral(sda
, PinMap_I2C_SDA
);
44 I2CName i2c_scl
= (I2CName
)pinmap_peripheral(scl
, PinMap_I2C_SCL
);
45 obj
->i2c
= (I2C_Type
*)pinmap_merge(i2c_sda
, i2c_scl
);
46 MBED_ASSERT((int)obj
->i2c
!= NC
);
49 switch ((int)obj
->i2c
) {
50 case I2C_0
: SIM
->SCGC5
|= 1 << 13; SIM
->SCGC4
|= 1 << 6; break;
51 case I2C_1
: SIM
->SCGC5
|= 1 << 11; SIM
->SCGC4
|= 1 << 7; break;
54 // set default frequency at 100k
55 i2c_frequency(obj
, 100000);
57 // enable I2C interface
60 pinmap_pinout(sda
, PinMap_I2C_SDA
);
61 pinmap_pinout(scl
, PinMap_I2C_SCL
);
64 int i2c_start(i2c_t
*obj
) {
67 // if we are in the middle of a transaction
68 // activate the repeat_start flag
69 if (obj
->i2c
->S
& I2C_S_BUSY_MASK
) {
70 // KL25Z errata sheet: repeat start cannot be generated if the
71 // I2Cx_F[MULT] field is set to a non-zero value
72 temp
= obj
->i2c
->F
>> 6;
75 for (i
= 0; i
< 100; i
++) __NOP();
76 obj
->i2c
->F
|= temp
<< 6;
78 obj
->i2c
->C1
|= I2C_C1_MST_MASK
;
79 obj
->i2c
->C1
|= I2C_C1_TX_MASK
;
84 int i2c_stop(i2c_t
*obj
) {
85 volatile uint32_t n
= 0;
86 obj
->i2c
->C1
&= ~I2C_C1_MST_MASK
;
87 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
89 // It seems that there are timing problems
90 // when there is no waiting time after a STOP.
91 // This wait is also included on the samples
92 // code provided with the freedom board
93 for (n
= 0; n
< 100; n
++) __NOP();
97 static int timeout_status_poll(i2c_t
*obj
, uint32_t mask
) {
98 uint32_t i
, timeout
= 100000;
100 for (i
= 0; i
< timeout
; i
++) {
101 if (obj
->i2c
->S
& mask
)
108 // this function waits the end of a tx transfer and return the status of the transaction:
109 // 0: OK ack received
110 // 1: OK ack not received
112 static int i2c_wait_end_tx_transfer(i2c_t
*obj
) {
114 // wait for the interrupt flag
115 if (timeout_status_poll(obj
, I2C_S_IICIF_MASK
)) {
119 obj
->i2c
->S
|= I2C_S_IICIF_MASK
;
121 // wait transfer complete
122 if (timeout_status_poll(obj
, I2C_S_TCF_MASK
)) {
126 // check if we received the ACK or not
127 return obj
->i2c
->S
& I2C_S_RXAK_MASK
? 1 : 0;
130 // this function waits the end of a rx transfer and return the status of the transaction:
133 static int i2c_wait_end_rx_transfer(i2c_t
*obj
) {
134 // wait for the end of the rx transfer
135 if (timeout_status_poll(obj
, I2C_S_IICIF_MASK
)) {
139 obj
->i2c
->S
|= I2C_S_IICIF_MASK
;
144 static void i2c_send_nack(i2c_t
*obj
) {
145 obj
->i2c
->C1
|= I2C_C1_TXAK_MASK
; // NACK
148 static void i2c_send_ack(i2c_t
*obj
) {
149 obj
->i2c
->C1
&= ~I2C_C1_TXAK_MASK
; // ACK
152 static int i2c_do_write(i2c_t
*obj
, int value
) {
156 // init and wait the end of the transfer
157 return i2c_wait_end_tx_transfer(obj
);
160 static int i2c_do_read(i2c_t
*obj
, char * data
, int last
) {
166 *data
= (obj
->i2c
->D
& 0xFF);
168 // start rx transfer and wait the end of the transfer
169 return i2c_wait_end_rx_transfer(obj
);
172 void i2c_frequency(i2c_t
*obj
, int hz
) {
176 uint32_t p_error
= 0xffffffff;
180 uint32_t PCLK
= bus_frequency();
181 uint32_t pulse
= PCLK
/ (hz
* 2);
183 // we look for the values that minimize the error
185 // test all the MULT values
186 for (i
= 1; i
< 5; i
*=2) {
187 for (j
= 0; j
< 0x40; j
++) {
188 ref
= PCLK
/ (i
*ICR
[j
]);
189 if (ref
> (uint32_t)hz
)
192 if (error
< p_error
) {
199 pulse
= icr
| (mult
<< 6);
205 int i2c_read(i2c_t
*obj
, int address
, char *data
, int length
, int stop
) {
207 char dummy_read
, *ptr
;
209 if (i2c_start(obj
)) {
211 return I2C_ERROR_BUS_BUSY
;
214 if (i2c_do_write(obj
, (address
| 0x01))) {
216 return I2C_ERROR_NO_SLAVE
;
220 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
223 for (count
= 0; count
< (length
); count
++) {
224 ptr
= (count
== 0) ? &dummy_read
: &data
[count
- 1];
225 uint8_t stop_
= (count
== (length
- 1)) ? 1 : 0;
226 if (i2c_do_read(obj
, ptr
, stop_
)) {
232 // If not repeated start, send stop.
238 data
[count
-1] = obj
->i2c
->D
;
242 int i2c_write(i2c_t
*obj
, int address
, const char *data
, int length
, int stop
) {
245 if (i2c_start(obj
)) {
247 return I2C_ERROR_BUS_BUSY
;
250 if (i2c_do_write(obj
, (address
& 0xFE))) {
252 return I2C_ERROR_NO_SLAVE
;
255 for (i
= 0; i
< length
; i
++) {
256 if(i2c_do_write(obj
, data
[i
])) {
269 void i2c_reset(i2c_t
*obj
) {
273 int i2c_byte_read(i2c_t
*obj
, int last
) {
277 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
280 i2c_do_read(obj
, &data
, last
);
283 obj
->i2c
->C1
|= I2C_C1_TX_MASK
;
287 int i2c_byte_write(i2c_t
*obj
, int data
) {
289 obj
->i2c
->C1
|= I2C_C1_TX_MASK
;
291 return !i2c_do_write(obj
, (data
& 0xFF));
296 void i2c_slave_mode(i2c_t
*obj
, int enable_slave
) {
299 obj
->i2c
->C1
&= ~I2C_C1_MST_MASK
;
300 obj
->i2c
->C1
|= I2C_C1_IICIE_MASK
;
303 obj
->i2c
->C1
|= I2C_C1_MST_MASK
;
307 int i2c_slave_receive(i2c_t
*obj
) {
308 switch(obj
->i2c
->S
) {
319 int i2c_slave_read(i2c_t
*obj
, char *data
, int length
) {
325 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
328 dummy_read
= obj
->i2c
->D
;
329 if(i2c_wait_end_rx_transfer(obj
)) {
334 dummy_read
= obj
->i2c
->D
;
335 if(i2c_wait_end_rx_transfer(obj
)) {
339 // read (length - 1) bytes
340 for (count
= 0; count
< (length
- 1); count
++) {
341 data
[count
] = obj
->i2c
->D
;
342 if(i2c_wait_end_rx_transfer(obj
)) {
348 ptr
= (length
== 0) ? &dummy_read
: (uint8_t *)&data
[count
];
351 return (length
) ? (count
+ 1) : 0;
354 int i2c_slave_write(i2c_t
*obj
, const char *data
, int length
) {
358 obj
->i2c
->C1
|= I2C_C1_TX_MASK
;
360 for (i
= 0; i
< length
; i
++) {
361 if(i2c_do_write(obj
, data
[count
++]) == 2) {
367 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
369 // dummy rx transfer needed
370 // otherwise the master cannot generate a stop bit
372 if(i2c_wait_end_rx_transfer(obj
) == 2) {
379 void i2c_slave_address(i2c_t
*obj
, int idx
, uint32_t address
, uint32_t mask
) {
380 obj
->i2c
->A1
= address
& 0xfe;