Skip to content

Commit ba482c3

Browse files
committed
add raspi3-64 i2c driver
1 parent 6416a18 commit ba482c3

File tree

5 files changed

+173
-136
lines changed

5 files changed

+173
-136
lines changed

bsp/raspberry-pi/raspi3-64/.config

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
148148
# CONFIG_RT_USING_CAN is not set
149149
CONFIG_RT_USING_HWTIMER=y
150150
# CONFIG_RT_USING_CPUTIME is not set
151-
# CONFIG_RT_USING_I2C is not set
151+
CONFIG_RT_USING_I2C=y
152+
CONFIG_RT_I2C_DEBUG=y
153+
CONFIG_RT_USING_I2C_BITOPS=y
154+
# CONFIG_RT_I2C_BITOPS_DEBUG is not set
152155
CONFIG_RT_USING_PIN=y
153156
# CONFIG_RT_USING_ADC is not set
154157
# CONFIG_RT_USING_PWM is not set
@@ -420,36 +423,6 @@ CONFIG_RT_USING_POSIX=y
420423
# CONFIG_PKG_USING_VT100 is not set
421424
# CONFIG_PKG_USING_ULAPACK is not set
422425
# CONFIG_PKG_USING_UKAL is not set
423-
424-
#
425-
# Privated Packages of RealThread
426-
#
427-
# CONFIG_PKG_USING_CODEC is not set
428-
# CONFIG_PKG_USING_PLAYER is not set
429-
# CONFIG_PKG_USING_MPLAYER is not set
430-
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
431-
# CONFIG_PKG_USING_JS_PERSIMMON is not set
432-
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
433-
434-
#
435-
# Network Utilities
436-
#
437-
# CONFIG_PKG_USING_WICED is not set
438-
# CONFIG_PKG_USING_CLOUDSDK is not set
439-
# CONFIG_PKG_USING_POWER_MANAGER is not set
440-
# CONFIG_PKG_USING_RT_OTA is not set
441-
# CONFIG_PKG_USING_RDBD_SRC is not set
442-
# CONFIG_PKG_USING_RTINSIGHT is not set
443-
# CONFIG_PKG_USING_SMARTCONFIG is not set
444-
# CONFIG_PKG_USING_RTX is not set
445-
# CONFIG_RT_USING_TESTCASE is not set
446-
# CONFIG_PKG_USING_NGHTTP2 is not set
447-
# CONFIG_PKG_USING_AVS is not set
448-
# CONFIG_PKG_USING_JOYLINK is not set
449-
# CONFIG_PKG_USING_STS is not set
450-
# CONFIG_PKG_USING_DLMS is not set
451-
# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
452-
# CONFIG_PKG_USING_ZBAR is not set
453426
CONFIG_BCM2836_SOC=y
454427
# CONFIG_BSP_SUPPORT_FPU is not set
455428

@@ -468,7 +441,9 @@ CONFIG_BSP_USING_CORETIMER=y
468441
CONFIG_BSP_USING_SYSTIMER=y
469442
CONFIG_RT_USING_SYSTIMER1=y
470443
CONFIG_RT_USING_SYSTIMER3=y
471-
# CONFIG_BSP_USING_I2C is not set
444+
CONFIG_BSP_USING_I2C=y
445+
# CONFIG_BSP_USING_I2C0 is not set
446+
CONFIG_BSP_USING_I2C1=y
472447
# CONFIG_BSP_USING_SPI is not set
473448
CONFIG_BSP_USING_WDT=y
474449
# CONFIG_BSP_USING_RTC is not set

bsp/raspberry-pi/raspi3-64/driver/board.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ void rt_hw_board_init(void)
100100
armv8_map(0x40000000, 0x40000000, 0x1000, MEM_ATTR_IO);//core timer
101101
armv8_map(0x3F300000, 0x3F300000, 0x1000, MEM_ATTR_IO);//sdio
102102
armv8_map(0xc00000, 0xc00000, 0x1000, MEM_ATTR_IO);//mbox
103+
armv8_map(0x3f804000, 0x3f804000, 0x1000, MEM_ATTR_IO);//i2c0
104+
armv8_map(0x3f205000, 0x3f205000, 0x1000, MEM_ATTR_IO);//i2c1
103105
mmu_enable();
104106

105107
/* initialize hardware interrupt */

bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c

Lines changed: 156 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006-2019, RT-Thread Development Team
2+
* Copyright (c) 2006-2020, RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -8,55 +8,103 @@
88
* 2019-07-29 zdzn first version
99
*/
1010

11+
#include "raspi.h"
1112
#include "drv_i2c.h"
1213

13-
#if defined (BSP_USING_I2C0)
14-
#define I2C1BUS_NAME "i2c0"
15-
#endif /*BSP_USING_I2C0*/
16-
17-
#if defined (BSP_USING_I2C1)
18-
#define I2C2BUS_NAME "i2c1"
19-
#endif /*BSP_USING_I2C1*/
20-
21-
static int i2c_byte_wait_us = 0;
22-
23-
#ifdef BSP_USING_I2C0
14+
//Maybe redefined
15+
typedef unsigned long rt_ubase_t;
16+
typedef rt_ubase_t rt_size_t;
2417

25-
static struct raspi_i2c_bus raspi_i2c0 =
18+
rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag)
2619
{
27-
.device_name = I2C1BUS_NAME,
28-
};
20+
rt_uint32_t status;
21+
rt_uint32_t remaining = len;
22+
rt_uint32_t i = 0;
23+
rt_uint8_t reason = BCM283X_I2C_REASON_OK;
24+
25+
/* Clear FIFO */
26+
BCM283X_BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
27+
/* Clear Status */
28+
BCM283X_BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
29+
/* Set Data Length */
30+
BCM283X_BSC_DLEN(base) = len;
31+
if (flag)
32+
{
33+
/* Start read */
34+
BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ;
35+
/* wait for transfer to complete */
36+
while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
37+
{
38+
/* we must empty the FIFO as it is populated and not use any delay */
39+
while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
40+
{
41+
/* Read from FIFO, no barrier */
42+
buf[i] = BCM283X_BSC_FIFO(base);
43+
i++;
44+
remaining--;
45+
}
46+
}
47+
/* transfer has finished - grab any remaining stuff in FIFO */
48+
while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
49+
{
50+
/* Read from FIFO, no barrier */
51+
buf[i] = BCM283X_BSC_FIFO(base);
52+
i++;
53+
remaining--;
54+
}
55+
}
56+
else
57+
{
58+
/* pre populate FIFO with max buffer */
59+
while (remaining && (i < BSC_FIFO_SIZE))
60+
{
61+
BCM283X_BSC_FIFO(base) = buf[i];
62+
i++;
63+
remaining--;
64+
}
2965

30-
static struct raspi_master_config_t raspi_i2c0_cfg =
31-
{
32-
.sdl_pin = BCM_GPIO_PIN_0,
33-
.scl_pin = BCM_GPIO_PIN_1,
34-
.sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
35-
.scl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
36-
.slave_address = 8,
37-
.bsc_base = (PER_BASE + BCM283X_BSC0_BASE),
38-
.clk_div = BCM283X_I2C_CLOCK_DIVIDER_148,
39-
};
66+
/* Enable device and start transfer */
67+
BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST;
4068

41-
#endif /* RT_USING_HW_I2C1 */
69+
/* Transfer is over when BCM2835_BSC_S_DONE */
70+
while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
71+
{
72+
while (remaining && (BCM283X_BSC_S(base) & BSC_S_TXD))
73+
{
74+
/* Write to FIFO */
75+
BCM283X_BSC_FIFO(base) = buf[i];
76+
i++;
77+
remaining--;
78+
}
79+
}
80+
}
4281

43-
#ifdef BSP_USING_I2C1
44-
static struct raspi_i2c_bus raspi_i2c1 =
45-
{
46-
.device_name = I2C2BUS_NAME,
47-
};
82+
status = BCM283X_BSC_S(base);
83+
if (status & BSC_S_ERR)
84+
{
85+
reason = BCM283X_I2C_REASON_ERROR_NACK;
86+
}
87+
else if (status & BSC_S_CLKT)
88+
{
89+
reason = BCM283X_I2C_REASON_ERROR_CLKT;
90+
}
91+
else if (remaining)
92+
{
93+
reason = BCM283X_I2C_REASON_ERROR_DATA;
94+
}
95+
BCM283X_BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE);
96+
97+
return reason;
98+
}
4899

49-
static struct raspi_master_config_t raspi_i2c1_cfg =
100+
struct raspi_i2c_hw_config
50101
{
51-
.sdl_pin = BCM_GPIO_PIN_2,
52-
.scl_pin = BCM_GPIO_PIN_3,
53-
.sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
54-
.scl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
55-
.slave_address = 9,
56-
.bsc_base = (PER_BASE + BCM283X_BSC1_BASE),
57-
.clk_div = BCM283X_I2C_CLOCK_DIVIDER_148,
102+
rt_uint8_t bsc_num;
103+
rt_uint8_t sdl_pin;
104+
rt_uint8_t scl_pin;
105+
rt_uint8_t sdl_mode;
106+
rt_uint8_t scl_mode;
58107
};
59-
#endif /* RT_USING_HW_I2C2 */
60108

61109
#if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1))
62110

@@ -70,58 +118,32 @@ static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
70118
rt_uint32_t,
71119
rt_uint32_t);
72120

73-
void i2c_master_init(struct raspi_master_config_t *cfg)
74-
{
75-
volatile rt_uint32_t addr;
76-
rt_uint32_t data;
77-
78-
bcm283x_gpio_fsel(cfg->sdl_pin, cfg->sdl_pin_mode); /* SDA */
79-
bcm283x_gpio_fsel(cfg->scl_pin, cfg->scl_pin_mode); /* SCL */
80-
81-
addr = cfg->bsc_base + BCM283X_BSC_DIV;
82-
data = bcm283x_peri_read(addr);
83-
i2c_byte_wait_us = ( data * 1000000 / BCM283X_CORE_CLK_HZ) * 9;
84-
85-
addr = cfg->bsc_base + BCM283X_BSC_DIV;
86-
bcm283x_peri_write(addr, cfg->clk_div);
87-
88-
//update
89-
i2c_byte_wait_us = (cfg->clk_div * 1000000 * 9 / BCM283X_CORE_CLK_HZ);
90-
}
91-
121+
static rt_uint32_t i2c_byte_wait_us = 0;
92122
static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
93123
struct rt_i2c_msg msgs[],
94124
rt_uint32_t num)
95125
{
96-
volatile rt_uint32_t addr;
97-
struct raspi_i2c_bus *raspi_i2c;
98126
rt_size_t i;
127+
rt_uint8_t reason;
99128
RT_ASSERT(bus != RT_NULL);
100-
raspi_i2c = (struct raspi_i2c_bus *) bus;
101-
raspi_i2c->msg = msgs;
102-
raspi_i2c->msg_ptr = 0;
103-
raspi_i2c->msg_cnt = num;
104-
raspi_i2c->dptr = 0;
105129

106-
addr = raspi_i2c->cfg->bsc_base + BCM283X_BSC_A;
107-
bcm283x_peri_write(addr, msgs->addr);
130+
volatile rt_base_t base = (volatile rt_base_t)(bus->parent.user_data);
131+
132+
if (bus->addr == 0)
133+
base = BCM283X_BSC0_BASE;
134+
else
135+
base = BCM283X_BSC1_BASE;
136+
137+
BCM283X_BSC_A(base) = msgs->addr;
108138

109139
for (i = 0; i < num; i++)
110140
{
111-
if ( raspi_i2c->msg[i].flags & RT_I2C_RD )
112-
{
113-
bcm283x_i2c_read(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num);
114-
}
141+
if (msgs[i].flags & RT_I2C_RD)
142+
reason = i2c_read_or_write(base, msgs->buf, msgs->len, 1);
115143
else
116-
{
117-
bcm283x_i2c_write(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num);
118-
}
144+
reason = i2c_read_or_write(base, msgs->buf, msgs->len, 0);
119145
}
120-
raspi_i2c->msg = RT_NULL;
121-
raspi_i2c->msg_ptr = 0;
122-
raspi_i2c->msg_cnt = 0;
123-
raspi_i2c->dptr = 0;
124-
return i;
146+
return (reason == 0)? i : 0;
125147
}
126148

127149
static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
@@ -134,7 +156,7 @@ static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
134156
rt_uint32_t cmd,
135157
rt_uint32_t arg)
136158
{
137-
return RT_ERROR;
159+
return RT_EOK;
138160
}
139161

140162
static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
@@ -144,33 +166,72 @@ static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
144166
.i2c_bus_control = raspi_i2c_bus_control,
145167
};
146168

147-
static rt_err_t raspi_i2c_configure(struct raspi_i2c_bus *bus, struct raspi_master_config_t *cfg)
169+
170+
static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg)
148171
{
149-
RT_ASSERT(bus != RT_NULL);
150172
RT_ASSERT(cfg != RT_NULL);
151173

152-
bus->device.ops = &raspi_i2c_ops;
153-
bus->cfg = cfg;
174+
volatile rt_uint32_t base = cfg->scl_mode ? BCM283X_BSC1_BASE : BCM283X_BSC0_BASE;
175+
176+
GPIO_FSEL(cfg->sdl_pin, cfg->sdl_mode); /* SDA */
177+
GPIO_FSEL(cfg->scl_pin, cfg->scl_mode); /* SCL */
178+
/* use 0xFFFE mask to limit a max value and round down any odd number */
179+
rt_uint32_t divider = (BCM283X_CORE_CLK_HZ / 10000) & 0xFFFE;
180+
BCM283X_BSC_DIV(base) = (rt_uint16_t) divider;
181+
i2c_byte_wait_us = (divider * 1000000 * 9 / BCM283X_CORE_CLK_HZ);
154182

155-
i2c_master_init(cfg);
156183
return RT_EOK;
157184
}
158185
#endif
159186

160-
int rt_hw_i2c_init(void)
187+
#if defined (BSP_USING_I2C0)
188+
#define I2C0_BUS_NAME "i2c0"
189+
static struct raspi_i2c_hw_config hw_device0 =
161190
{
191+
.bsc_num = 0,
192+
.sdl_pin = RPI_GPIO_P1_27,
193+
.scl_pin = RPI_GPIO_P1_28,
194+
.sdl_mode = BCM283X_GPIO_FSEL_ALT0,
195+
.scl_mode = BCM283X_GPIO_FSEL_ALT0,
196+
};
162197

163-
#if defined(BSP_USING_I2C0)
164-
raspi_i2c_configure(&raspi_i2c0 , &raspi_i2c0_cfg);
165-
rt_i2c_bus_device_register(&raspi_i2c0.device, raspi_i2c0.device_name);
166-
#endif /* BSP_USING_I2C1 */
198+
struct rt_i2c_bus_device device0 =
199+
{
200+
.ops = &raspi_i2c_ops,
201+
.addr = 0,
202+
};
167203

168-
#if defined(BSP_USING_I2C1)
204+
#endif
169205

170-
raspi_i2c_configure(&raspi_i2c1 , &raspi_i2c1_cfg);
171-
rt_i2c_bus_device_register(&raspi_i2c1.device, raspi_i2c1.device_name);
206+
#if defined (BSP_USING_I2C1)
207+
#define I2C1_BUS_NAME "i2c1"
208+
static struct raspi_i2c_hw_config hw_device1 =
209+
{
210+
.bsc_num = 1,
211+
.sdl_pin = RPI_GPIO_P1_03,
212+
.scl_pin = RPI_GPIO_P1_05,
213+
.sdl_mode = BCM283X_GPIO_FSEL_ALT0,
214+
.scl_mode = BCM283X_GPIO_FSEL_ALT0,
215+
};
216+
struct rt_i2c_bus_device device1 =
217+
{
218+
.ops = &raspi_i2c_ops,
219+
.addr = 1,
220+
};
172221

173-
#endif /* BSP_USING_I2C2 */
222+
#endif
223+
224+
int rt_hw_i2c_init(void)
225+
{
226+
#if defined(BSP_USING_I2C0)
227+
raspi_i2c_configure(&hw_device0);
228+
rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
229+
#endif
230+
231+
#if defined(BSP_USING_I2C1)
232+
raspi_i2c_configure(&hw_device1);
233+
rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
234+
#endif
174235

175236
return 0;
176237
}

0 commit comments

Comments
 (0)