1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-13 AisinoChip first implementation.
*/
#include <board.h>
#ifdef RT_USING_I2C_BITOPS
#include <rtdevice.h>
#include <drivers/pin.h>
#define I2C_BUS_NAME "i2cs"
/* user should change this to adapt specific board */
#define I2C_SCL_PIN GPIO_PIN_6
#define I2C_SCL_PORT GPIOD
#define I2C_SDA_PIN GPIO_PIN_7
#define I2C_SDA_PORT GPIOD
struct acm32_i2c_bit_data
{
struct
{
enum_GPIOx_t port;
rt_uint32_t pin;
} scl, sda;
};
static void _set_sda(void *data, rt_int32_t state)
{
struct acm32_i2c_bit_data* bd = data;
if (state)
{
HAL_GPIO_WritePin(bd->sda.port, bd->sda.pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(bd->sda.port, bd->sda.pin, GPIO_PIN_CLEAR);
}
}
static void _set_scl(void *data, rt_int32_t state)
{
struct acm32_i2c_bit_data* bd = data;
if (state)
{
HAL_GPIO_WritePin(bd->scl.port, bd->scl.pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(bd->scl.port, bd->scl.pin, GPIO_PIN_CLEAR);
}
}
static rt_int32_t _get_sda(void *data)
{
struct acm32_i2c_bit_data* bd = data;
return HAL_GPIO_ReadPin(bd->sda.port, bd->sda.pin);
}
static rt_int32_t _get_scl(void *data)
{
struct acm32_i2c_bit_data* bd = data;
return HAL_GPIO_ReadPin(bd->scl.port, bd->scl.pin);
}
static void acm32_udelay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
static void drv_i2c_gpio_init(const struct acm32_i2c_bit_data* bd)
{
GPIO_InitTypeDef GPIO_Handle;
GPIO_Handle.Pin = bd->sda.pin;
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Handle.Pull = GPIO_PULLUP;
GPIO_Handle.Alternate = GPIO_FUNCTION_0;
HAL_GPIO_Init(bd->sda.port, &GPIO_Handle);
GPIO_Handle.Pin = bd->scl.pin;
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Handle.Pull = GPIO_PULLUP;
GPIO_Handle.Alternate = GPIO_FUNCTION_0;
HAL_GPIO_Init(bd->scl.port, &GPIO_Handle);
_set_sda((void*)bd, 1);
_set_scl((void*)bd, 1);
}
int rt_soft_i2c_init(void)
{
static struct rt_i2c_bus_device i2c_device;
static const struct acm32_i2c_bit_data _i2c_bdata =
{
/* SCL */
{ I2C_SCL_PORT, I2C_SCL_PIN},
/* SDA */
{ I2C_SDA_PORT, I2C_SDA_PIN},
};
static const struct rt_i2c_bit_ops _i2c_bit_ops =
{
(void*)&_i2c_bdata,
_set_sda,
_set_scl,
_get_sda,
_get_scl,
acm32_udelay,
1,
100
};
drv_i2c_gpio_init(&_i2c_bdata);
i2c_device.priv = (void *)&_i2c_bit_ops;
rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME);
return 0;
}
INIT_DEVICE_EXPORT(rt_soft_i2c_init);
#endif /* RT_USING_I2C_BITOPS */
|