]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/i2c_api.c
1 /* mbed Microcontroller Library
2 * Copyright (c) 2006-2015 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
);
48 #if defined(TARGET_K20DX256)
49 switch ((int)obj
->i2c
) {
50 case I2C_0
: SIM
->SCGC4
|= SIM_SCGC4_I2C0_MASK
;
51 case I2C_1
: SIM
->SCGC4
|= SIM_SCGC4_I2C1_MASK
;
54 SIM
->SCGC4
|= SIM_SCGC4_I2C0_MASK
;
57 // set default frequency at 100k
58 i2c_frequency(obj
, 100000);
60 // enable I2C interface
63 pinmap_pinout(sda
, PinMap_I2C_SDA
);
64 pinmap_pinout(scl
, PinMap_I2C_SCL
);
65 /* enable open drain for I2C pins, only port b available */
66 uint32_t pin_n
= (uint32_t)(sda
& 0x7C) >> 2;
67 PORTB
->PCR
[pin_n
] |= PORT_PCR_ODE_MASK
;
68 pin_n
= (uint32_t)(scl
& 0x7C) >> 2;
69 PORTB
->PCR
[pin_n
] |= PORT_PCR_ODE_MASK
;
72 int i2c_start(i2c_t
*obj
) {
73 // if we are in the middle of a transaction
74 // activate the repeat_start flag
75 if (obj
->i2c
->S
& I2C_S_BUSY_MASK
) {
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
++)
98 static int timeout_status_poll(i2c_t
*obj
, uint32_t mask
) {
99 uint32_t i
, timeout
= 100000;
101 for (i
= 0; i
< timeout
; i
++) {
102 if (obj
->i2c
->S
& mask
)
109 // this function waits the end of a tx transfer and return the status of the transaction:
110 // 0: OK ack received
111 // 1: OK ack not received
113 static int i2c_wait_end_tx_transfer(i2c_t
*obj
) {
115 // wait for the interrupt flag
116 if (timeout_status_poll(obj
, I2C_S_IICIF_MASK
)) {
120 obj
->i2c
->S
|= I2C_S_IICIF_MASK
;
122 // wait transfer complete
123 if (timeout_status_poll(obj
, I2C_S_TCF_MASK
)) {
127 // check if we received the ACK or not
128 return obj
->i2c
->S
& I2C_S_RXAK_MASK
? 1 : 0;
131 // this function waits the end of a rx transfer and return the status of the transaction:
134 static int i2c_wait_end_rx_transfer(i2c_t
*obj
) {
135 // wait for the end of the rx transfer
136 if (timeout_status_poll(obj
, I2C_S_IICIF_MASK
)) {
140 obj
->i2c
->S
|= I2C_S_IICIF_MASK
;
145 static void i2c_send_nack(i2c_t
*obj
) {
146 obj
->i2c
->C1
|= I2C_C1_TXAK_MASK
; // NACK
149 static void i2c_send_ack(i2c_t
*obj
) {
150 obj
->i2c
->C1
&= ~I2C_C1_TXAK_MASK
; // ACK
153 static int i2c_do_write(i2c_t
*obj
, int value
) {
157 // init and wait the end of the transfer
158 return i2c_wait_end_tx_transfer(obj
);
161 static int i2c_do_read(i2c_t
*obj
, char * data
, int last
) {
168 *data
= (obj
->i2c
->D
& 0xFF);
170 // start rx transfer and wait the end of the transfer
171 return i2c_wait_end_rx_transfer(obj
);
174 void i2c_frequency(i2c_t
*obj
, int hz
) {
178 uint32_t p_error
= 0xffffffff;
182 uint32_t PCLK
= bus_frequency();
183 uint32_t pulse
= PCLK
/ (hz
* 2);
185 // we look for the values that minimize the error
187 // test all the MULT values
188 for (i
= 1; i
< 5; i
*=2) {
189 for (j
= 0; j
< 0x40; j
++) {
190 ref
= PCLK
/ (i
*ICR
[j
]);
191 if (ref
> (uint32_t)hz
)
194 if (error
< p_error
) {
201 pulse
= icr
| (mult
<< 6);
207 int i2c_read(i2c_t
*obj
, int address
, char *data
, int length
, int stop
) {
209 char dummy_read
, *ptr
;
211 if (i2c_start(obj
)) {
213 return I2C_ERROR_BUS_BUSY
;
216 if (i2c_do_write(obj
, (address
| 0x01))) {
218 return I2C_ERROR_NO_SLAVE
;
222 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
225 for (count
= 0; count
< (length
); count
++) {
226 ptr
= (count
== 0) ? &dummy_read
: &data
[count
- 1];
227 uint8_t stop_
= (count
== (length
- 1)) ? 1 : 0;
228 if (i2c_do_read(obj
, ptr
, stop_
)) {
234 // If not repeated start, send stop.
239 data
[count
-1] = obj
->i2c
->D
;
243 int i2c_write(i2c_t
*obj
, int address
, const char *data
, int length
, int stop
) {
246 if (i2c_start(obj
)) {
248 return I2C_ERROR_BUS_BUSY
;
251 if (i2c_do_write(obj
, (address
& 0xFE))) {
253 return I2C_ERROR_NO_SLAVE
;
256 for (i
= 0; i
< length
; i
++) {
257 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
) {
320 int i2c_slave_read(i2c_t
*obj
, char *data
, int length
) {
326 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
329 dummy_read
= obj
->i2c
->D
;
330 if (i2c_wait_end_rx_transfer(obj
))
334 dummy_read
= obj
->i2c
->D
;
335 if (i2c_wait_end_rx_transfer(obj
))
338 // read (length - 1) bytes
339 for (count
= 0; count
< (length
- 1); count
++) {
340 data
[count
] = obj
->i2c
->D
;
341 if (i2c_wait_end_rx_transfer(obj
))
346 ptr
= (length
== 0) ? &dummy_read
: (uint8_t *)&data
[count
];
349 return (length
) ? (count
+ 1) : 0;
352 int i2c_slave_write(i2c_t
*obj
, const char *data
, int length
) {
356 obj
->i2c
->C1
|= I2C_C1_TX_MASK
;
358 for (i
= 0; i
< length
; i
++) {
359 if (i2c_do_write(obj
, data
[count
++]) == 2)
364 obj
->i2c
->C1
&= ~I2C_C1_TX_MASK
;
366 // dummy rx transfer needed
367 // otherwise the master cannot generate a stop bit
369 if (i2c_wait_end_rx_transfer(obj
) == 2)
375 void i2c_slave_address(i2c_t
*obj
, int idx
, uint32_t address
, uint32_t mask
) {
376 obj
->i2c
->A1
= address
& 0xfe;