Skip to content

Commit 4c69f72

Browse files
SidLeungcalvinatintel
authored andcommitted
Added support for Quark I2C interfaces: I2C0 and I2C1.
Additions: 1. Ported Quark I2C driver to ARC/CoreLibs, located at system/libarc32_arduino101/drivers. 2. Created the I2C Adapters, located at cores/arduino. Modifications: 1. Platform.h - added number of I2C interface definition.
1 parent 7dcc074 commit 4c69f72

File tree

22 files changed

+2312
-429
lines changed

22 files changed

+2312
-429
lines changed

cores/arduino/i2c.c

+198-164
Large diffs are not rendered by default.

cores/arduino/i2c.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,28 @@
2323
#define i2c_h
2424

2525
#include <inttypes.h>
26+
#include <stdbool.h>
27+
#include "ss_i2c_iface.h"
28+
2629
#ifdef __cplusplus
2730
extern "C"{
2831
#endif
2932

3033
#define I2C_OK 0
3134
#define I2C_TIMEOUT -10
32-
#define I2C_ERROR -11
35+
#define I2C_ERROR -20 /* Qi, 2016. */
3336
#define I2C_ERROR_ADDRESS_NOACK (-2)
3437
#define I2C_ERROR_DATA_NOACK (-3)
3538
#define I2C_ERROR_OTHER (-4)
3639

3740
#define I2C_ABRT_7B_ADDR_NOACK (1 << 0)
3841
#define I2C_ABRT_TXDATA_NOACK (1 << 3)
3942

40-
int i2c_openadapter(void);
41-
int i2c_openadapter_speed(int);
42-
void i2c_setslave(uint8_t addr);
43-
int i2c_writebytes(uint8_t *bytes, uint8_t length, bool no_stop);
44-
int i2c_readbytes(uint8_t *buf, int length, bool no_stop);
43+
int i2c_openadapter(I2C_CONTROLLER controller_id);
44+
int i2c_openadapter_speed(I2C_CONTROLLER controller_id, int i2c_speed);
45+
void i2c_setslave(I2C_CONTROLLER controller_id, uint8_t addr);
46+
int i2c_writebytes(I2C_CONTROLLER controller_id, uint8_t *bytes, uint8_t length, bool no_stop);
47+
int i2c_readbytes(I2C_CONTROLLER controller_id, uint8_t *buf, int length, bool no_stop);
4548

4649
#ifdef __cplusplus
4750
}

cores/arduino/soc_i2c.c

+331
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
/*
2+
* soc_i2c.c - i2c library layer
3+
*
4+
* Copyright (C) 2015, 2016 Intel Corporation
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*
20+
*/
21+
22+
#include <stdbool.h>
23+
#include "intel_qrk_i2c.h"
24+
#include "variant.h"
25+
#include "soc_i2c.h"
26+
#include "i2c.h"
27+
28+
#define TIMEOUT_MS 16
29+
30+
static volatile uint8_t soc_i2c_master_tx_complete[NUM_SOC_I2C];
31+
static volatile uint8_t soc_i2c_master_rx_complete[NUM_SOC_I2C];
32+
static volatile uint8_t soc_i2c_err_detect[NUM_SOC_I2C];
33+
static volatile uint32_t soc_i2c_err_source[NUM_SOC_I2C];
34+
35+
static volatile uint32_t soc_i2c_slave_address[NUM_SOC_I2C] = {0, 0};
36+
37+
static void soc_i2c0_master_rx_callback(uint32_t dev_id)
38+
{
39+
soc_i2c_master_rx_complete[SOC_I2C_0] = 1;
40+
}
41+
42+
static void soc_i2c1_master_rx_callback(uint32_t dev_id)
43+
{
44+
soc_i2c_master_rx_complete[SOC_I2C_1] = 1;
45+
}
46+
47+
static void soc_i2c0_master_tx_callback(uint32_t dev_id)
48+
{
49+
soc_i2c_master_tx_complete[SOC_I2C_0] = 1;
50+
}
51+
52+
static void soc_i2c1_master_tx_callback(uint32_t dev_id)
53+
{
54+
soc_i2c_master_tx_complete[SOC_I2C_1] = 1;
55+
}
56+
57+
static void soc_i2c0_err_callback(uint32_t dev_id)
58+
{
59+
soc_i2c_err_detect[SOC_I2C_0] = 1;
60+
soc_i2c_err_source[SOC_I2C_0] = dev_id;
61+
}
62+
63+
static void soc_i2c1_err_callback(uint32_t dev_id)
64+
{
65+
soc_i2c_err_detect[SOC_I2C_1] = 1;
66+
soc_i2c_err_source[SOC_I2C_1] = dev_id;
67+
}
68+
69+
static void (*soc_i2c0_slave_rx_user_callback)(int, void *) = NULL;
70+
static void *soc_i2c0_slave_rx_user_cb_data_ptr = NULL;
71+
72+
static void (*soc_i2c1_slave_rx_user_callback)(int, void *) = NULL;
73+
static void *soc_i2c1_slave_rx_user_cb_data_ptr = NULL;
74+
75+
static void (*soc_i2c0_slave_tx_user_callback)(void *) = NULL;
76+
static void *soc_i2c0_slave_tx_user_cb_data_ptr = NULL;
77+
78+
static void (*soc_i2c1_slave_tx_user_callback)(void *) = NULL;
79+
static void *soc_i2c1_slave_tx_user_cb_data_ptr = NULL;
80+
81+
static void soc_i2c0_slave_rx_callback(uint32_t bytes)
82+
{
83+
if (soc_i2c0_slave_rx_user_callback) {
84+
soc_i2c0_slave_rx_user_callback((int)bytes, soc_i2c0_slave_rx_user_cb_data_ptr);
85+
}
86+
}
87+
88+
static void soc_i2c1_slave_rx_callback(uint32_t bytes)
89+
{
90+
if (soc_i2c1_slave_rx_user_callback) {
91+
soc_i2c1_slave_rx_user_callback((int)bytes, soc_i2c1_slave_rx_user_cb_data_ptr);
92+
}
93+
}
94+
95+
static void soc_i2c0_slave_tx_callback(uint32_t bytes)
96+
{
97+
if (soc_i2c0_slave_tx_user_callback) {
98+
soc_i2c0_slave_tx_user_callback(soc_i2c0_slave_tx_user_cb_data_ptr);
99+
}
100+
}
101+
102+
static void soc_i2c1_slave_tx_callback(uint32_t bytes)
103+
{
104+
if (soc_i2c1_slave_tx_user_callback) {
105+
soc_i2c1_slave_tx_user_callback(soc_i2c1_slave_tx_user_cb_data_ptr);
106+
}
107+
}
108+
109+
void soc_i2c_slave_set_rx_user_callback(SOC_I2C_CONTROLLER controller_id, void (*onReceiveCallback)(int, void *), void *callerDataPtr)
110+
{
111+
if (controller_id == SOC_I2C_0) {
112+
soc_i2c0_slave_rx_user_callback = onReceiveCallback;
113+
soc_i2c0_slave_rx_user_cb_data_ptr = callerDataPtr;
114+
} else {
115+
soc_i2c1_slave_rx_user_callback = onReceiveCallback;
116+
soc_i2c1_slave_rx_user_cb_data_ptr = callerDataPtr;
117+
}
118+
}
119+
120+
void soc_i2c_slave_set_tx_user_callback(SOC_I2C_CONTROLLER controller_id, void (*onRequestCallback)(void *), void *callerDataPtr)
121+
{
122+
if (controller_id == SOC_I2C_0) {
123+
soc_i2c0_slave_tx_user_callback = onRequestCallback;
124+
soc_i2c0_slave_tx_user_cb_data_ptr = callerDataPtr;
125+
} else {
126+
soc_i2c1_slave_tx_user_callback = onRequestCallback;
127+
soc_i2c1_slave_tx_user_cb_data_ptr = callerDataPtr;
128+
}
129+
}
130+
131+
static int soc_i2c_master_wait_rx_or_err(SOC_I2C_CONTROLLER controller_id)
132+
{
133+
uint64_t timeout = TIMEOUT_MS * 200;
134+
while (timeout--) {
135+
if (soc_i2c_err_detect[controller_id]) {
136+
if (soc_i2c_err_source[controller_id] &
137+
(I2C_ABRT_7B_ADDR_NOACK | I2C_ABRT_10ADDR1_NOACK | I2C_ABRT_10ADDR2_NOACK)) {
138+
return I2C_ERROR_ADDRESS_NOACK; // NACK on transmit of address
139+
}
140+
else if (soc_i2c_err_source[controller_id] & I2C_ABRT_TXDATA_NOACK) {
141+
return I2C_ERROR_DATA_NOACK; // NACK on transmit of data
142+
} else {
143+
return I2C_ERROR_OTHER; // other error
144+
}
145+
}
146+
if (soc_i2c_master_rx_complete[controller_id]) {
147+
return I2C_OK;
148+
}
149+
delayMicroseconds(10);
150+
}
151+
return I2C_TIMEOUT;
152+
}
153+
154+
static int soc_i2c_master_wait_tx_or_err(SOC_I2C_CONTROLLER controller_id)
155+
{
156+
uint64_t timeout = TIMEOUT_MS * 200;
157+
while (timeout--) {
158+
if (soc_i2c_err_detect[controller_id]) {
159+
if (soc_i2c_err_source[controller_id] &
160+
(I2C_ABRT_7B_ADDR_NOACK | I2C_ABRT_10ADDR1_NOACK | I2C_ABRT_10ADDR2_NOACK)) {
161+
return I2C_ERROR_ADDRESS_NOACK; // NACK on transmit of address
162+
}
163+
else if (soc_i2c_err_source[controller_id] & I2C_ABRT_TXDATA_NOACK) {
164+
return I2C_ERROR_DATA_NOACK; // NACK on transmit of data
165+
} else {
166+
return I2C_ERROR_OTHER; // other error
167+
}
168+
}
169+
if (soc_i2c_master_tx_complete[controller_id]) {
170+
return I2C_OK;
171+
}
172+
delayMicroseconds(10);
173+
}
174+
return I2C_TIMEOUT;
175+
}
176+
177+
static int soc_i2c_wait_dev_ready(SOC_I2C_CONTROLLER controller_id,
178+
bool no_stop)
179+
{
180+
uint64_t timeout = TIMEOUT_MS * 200;
181+
int ret = 0;
182+
while (timeout--) {
183+
ret = soc_i2c_status(controller_id, no_stop);
184+
if (ret == I2C_OK) {
185+
return I2C_OK;
186+
}
187+
if (ret == I2C_BUSY) {
188+
delayMicroseconds(10);
189+
}
190+
}
191+
return I2C_TIMEOUT - ret;
192+
}
193+
194+
int soc_i2c_open_adapter(SOC_I2C_CONTROLLER controller_id, uint32_t address, int i2c_speed, int i2c_addr_mode)
195+
{
196+
int ret = 0;
197+
198+
if (controller_id == SOC_I2C_0) {
199+
SET_PIN_MODE(20, I2C_MUX_MODE);
200+
SET_PIN_MODE(21, I2C_MUX_MODE);
201+
202+
SET_PIN_PULLUP(20, 1);
203+
SET_PIN_PULLUP(21, 1);
204+
} else {
205+
SET_PIN_MODE(22, I2C_MUX_MODE);
206+
SET_PIN_MODE(23, I2C_MUX_MODE);
207+
208+
SET_PIN_PULLUP(22, 1);
209+
SET_PIN_PULLUP(23, 1);
210+
}
211+
212+
i2c_cfg_data_t i2c_cfg;
213+
memset(&i2c_cfg, 0, sizeof(i2c_cfg_data_t));
214+
215+
i2c_cfg.speed = i2c_speed;
216+
i2c_cfg.addressing_mode = i2c_addr_mode;
217+
if (address) {
218+
i2c_cfg.mode_type = I2C_SLAVE;
219+
if (controller_id == SOC_I2C_0) {
220+
i2c_cfg.cb_err = soc_i2c0_err_callback;
221+
i2c_cfg.cb_rx = soc_i2c0_slave_rx_callback;
222+
i2c_cfg.cb_tx = soc_i2c0_slave_tx_callback;
223+
} else {
224+
i2c_cfg.cb_err = soc_i2c1_err_callback;
225+
i2c_cfg.cb_rx = soc_i2c1_slave_rx_callback;
226+
i2c_cfg.cb_tx = soc_i2c1_slave_tx_callback;
227+
}
228+
} else {
229+
i2c_cfg.mode_type = I2C_MASTER;
230+
231+
if (controller_id == SOC_I2C_0) {
232+
i2c_cfg.cb_tx = soc_i2c0_master_tx_callback;
233+
i2c_cfg.cb_rx = soc_i2c0_master_rx_callback;
234+
i2c_cfg.cb_err = soc_i2c0_err_callback;
235+
} else {
236+
i2c_cfg.cb_tx = soc_i2c1_master_tx_callback;
237+
i2c_cfg.cb_rx = soc_i2c1_master_rx_callback;
238+
i2c_cfg.cb_err = soc_i2c1_err_callback;
239+
}
240+
soc_i2c_master_tx_complete[controller_id] = 0;
241+
soc_i2c_master_rx_complete[controller_id] = 0;
242+
}
243+
i2c_cfg.slave_adr = address;
244+
soc_i2c_err_detect[controller_id] = 0;
245+
soc_i2c_err_source[controller_id] = 0;
246+
247+
soc_i2c_set_config(controller_id, &i2c_cfg);
248+
soc_i2c_clock_enable(controller_id);
249+
250+
ret = soc_i2c_wait_dev_ready(controller_id, false);
251+
252+
return ret;
253+
}
254+
255+
void soc_i2c_close_adapter(SOC_I2C_CONTROLLER controller_id)
256+
{
257+
soc_i2c_deconfig(controller_id);
258+
soc_i2c_clock_disable(controller_id);
259+
260+
if (controller_id == SOC_I2C_0) {
261+
SET_PIN_MODE(20, GPIO_MUX_MODE);
262+
SET_PIN_MODE(21, GPIO_MUX_MODE);
263+
} else {
264+
SET_PIN_MODE(22, GPIO_MUX_MODE);
265+
SET_PIN_MODE(23, GPIO_MUX_MODE);
266+
}
267+
268+
return;
269+
}
270+
271+
void soc_i2c_set_speed(SOC_I2C_CONTROLLER controller_id, uint32_t speed)
272+
{
273+
soc_i2c_set_transfer_speed(controller_id, speed);
274+
}
275+
276+
void soc_i2c_set_address_mode(SOC_I2C_CONTROLLER controller_id, uint32_t mode)
277+
{
278+
soc_i2c_set_transfer_mode(controller_id, mode);
279+
}
280+
281+
void soc_i2c_master_set_slave_address(SOC_I2C_CONTROLLER controller_id, uint32_t addr)
282+
{
283+
soc_i2c_slave_address[controller_id] = addr;
284+
return;
285+
}
286+
287+
void soc_i2c_slave_set_rx_user_buffer(SOC_I2C_CONTROLLER controller_id, uint8_t *buffer, uint8_t length)
288+
{
289+
soc_i2c_slave_enable_rx(controller_id, buffer, length);
290+
}
291+
292+
void soc_i2c_slave_set_tx_user_buffer(SOC_I2C_CONTROLLER controller_id, uint8_t *buffer, uint8_t length)
293+
{
294+
soc_i2c_slave_enable_tx(controller_id, buffer, length);
295+
}
296+
297+
int soc_i2c_master_witebytes(SOC_I2C_CONTROLLER controller_id, uint8_t *buf, uint8_t length, bool no_stop)
298+
{
299+
int ret;
300+
301+
soc_i2c_master_tx_complete[controller_id] = 0;
302+
soc_i2c_err_detect[controller_id] = 0;
303+
soc_i2c_err_source[controller_id] = 0;
304+
soc_i2c_master_transfer(controller_id, buf, length, 0, 0,
305+
soc_i2c_slave_address[controller_id], no_stop);
306+
ret = soc_i2c_master_wait_tx_or_err(controller_id);
307+
if (ret)
308+
return ret;
309+
ret = soc_i2c_wait_dev_ready(controller_id, no_stop);
310+
if (ret)
311+
return ret;
312+
return length;
313+
}
314+
315+
int soc_i2c_master_readbytes(SOC_I2C_CONTROLLER controller_id, uint8_t *buf, int length, bool no_stop)
316+
{
317+
int ret;
318+
319+
soc_i2c_master_rx_complete[controller_id] = 0;
320+
soc_i2c_err_detect[controller_id] = 0;
321+
soc_i2c_err_source[controller_id] = 0;
322+
soc_i2c_master_transfer(controller_id, 0, 0, buf, length,
323+
soc_i2c_slave_address[controller_id], no_stop);
324+
ret = soc_i2c_master_wait_rx_or_err(controller_id);
325+
if (ret)
326+
return ret;
327+
ret = soc_i2c_wait_dev_ready(controller_id, no_stop);
328+
if (ret)
329+
return ret;
330+
return length;
331+
}

0 commit comments

Comments
 (0)