@@ -46,14 +46,25 @@ enum i2c_rw {
46
46
};
47
47
48
48
/* This function delays for half of a SCL pulse, i.e. quarter of a period. */
49
- static inline void mgos_i2c_half_delay (struct mgos_i2c * c ) {
49
+ static inline void mgos_i2c_gpio_half_delay (struct mgos_i2c * c ) {
50
50
(mgos_nsleep100 )(c -> half_delay_n100 );
51
51
}
52
52
53
- static enum i2c_ack_type mgos_i2c_send_byte (struct mgos_i2c * c , uint8_t data );
53
+ static inline void mgos_i2c_gpio_release_scl (struct mgos_i2c * c ) {
54
+ mgos_gpio_write (c -> scl_gpio , 1 );
55
+ // mgos_i2c_gpio_half_delay(c);
56
+ /* check for clock stretching by slave */
57
+ mgos_gpio_set_mode (c -> scl_gpio , MGOS_GPIO_MODE_INPUT );
58
+ while (!mgos_gpio_read (c -> scl_gpio )) {
59
+ }
60
+ mgos_gpio_set_mode (c -> scl_gpio , MGOS_GPIO_MODE_OUTPUT_OD );
61
+ }
54
62
55
- static enum i2c_ack_type mgos_i2c_start (struct mgos_i2c * c , uint16_t addr ,
56
- enum i2c_rw mode ) {
63
+ static enum i2c_ack_type mgos_i2c_gpio_send_byte (struct mgos_i2c * c ,
64
+ uint8_t data );
65
+
66
+ static enum i2c_ack_type mgos_i2c_gpio_start (struct mgos_i2c * c , uint16_t addr ,
67
+ enum i2c_rw mode ) {
57
68
enum i2c_ack_type result ;
58
69
uint8_t address_byte = (uint8_t )(addr << 1 ) | mode ;
59
70
if (c -> debug ) {
@@ -65,52 +76,51 @@ static enum i2c_ack_type mgos_i2c_start(struct mgos_i2c *c, uint16_t addr,
65
76
}
66
77
mgos_gpio_write (c -> sda_gpio , 1 );
67
78
mgos_gpio_write (c -> scl_gpio , 1 );
68
- mgos_i2c_half_delay (c );
79
+ mgos_i2c_gpio_half_delay (c );
69
80
mgos_gpio_write (c -> sda_gpio , 0 );
70
- mgos_i2c_half_delay (c );
81
+ mgos_i2c_gpio_half_delay (c );
71
82
mgos_gpio_write (c -> scl_gpio , 0 );
72
- mgos_i2c_half_delay (c );
73
- result = mgos_i2c_send_byte (c , address_byte );
83
+ mgos_i2c_gpio_half_delay (c );
84
+ result = mgos_i2c_gpio_send_byte (c , address_byte );
74
85
c -> started = 1 ;
75
86
if (result != I2C_ACK ) mgos_i2c_stop (c );
76
87
return result ;
77
88
}
78
89
79
90
void mgos_i2c_stop (struct mgos_i2c * c ) {
80
91
if (!c -> started ) return ;
81
- mgos_i2c_half_delay (c );
92
+ mgos_i2c_gpio_half_delay (c );
82
93
mgos_gpio_write (c -> scl_gpio , 1 );
83
- mgos_i2c_half_delay (c );
94
+ mgos_i2c_gpio_half_delay (c );
84
95
mgos_gpio_write (c -> sda_gpio , 1 );
85
- mgos_i2c_half_delay (c );
96
+ mgos_i2c_gpio_half_delay (c );
86
97
c -> started = false;
87
98
if (c -> debug ) {
88
99
LOG (LL_DEBUG , (" stop" ));
89
100
}
90
101
}
91
102
92
- static enum i2c_ack_type mgos_i2c_send_byte (struct mgos_i2c * c , uint8_t data ) {
103
+ static enum i2c_ack_type mgos_i2c_gpio_send_byte (struct mgos_i2c * c ,
104
+ uint8_t data ) {
93
105
enum i2c_ack_type ret_val ;
94
106
int i , bit ;
95
107
96
108
mgos_gpio_write (c -> scl_gpio , 0 );
97
- mgos_i2c_half_delay (c );
109
+ mgos_i2c_gpio_half_delay (c );
98
110
for (i = 0 ; i < 8 ; i ++ ) {
99
111
bit = (data & (1 << (7 - i ))) ? 1 : 0 ;
100
112
mgos_gpio_write (c -> sda_gpio , bit );
101
- mgos_gpio_write (c -> scl_gpio , 1 );
102
- mgos_i2c_half_delay (c );
113
+ mgos_i2c_gpio_release_scl (c );
103
114
mgos_gpio_write (c -> scl_gpio , 0 );
104
- mgos_i2c_half_delay (c );
115
+ mgos_i2c_gpio_half_delay (c );
105
116
}
106
117
/* release the bus for slave to write ack */
107
118
mgos_gpio_write (c -> sda_gpio , 1 );
108
119
mgos_gpio_set_mode (c -> sda_gpio , MGOS_GPIO_MODE_INPUT );
109
- mgos_gpio_write (c -> scl_gpio , 1 );
110
- mgos_i2c_half_delay (c );
120
+ mgos_i2c_gpio_release_scl (c );
111
121
ret_val = mgos_gpio_read (c -> sda_gpio );
112
122
mgos_gpio_write (c -> scl_gpio , 0 );
113
- mgos_i2c_half_delay (c );
123
+ mgos_i2c_gpio_half_delay (c );
114
124
mgos_gpio_write (c -> sda_gpio , 0 );
115
125
mgos_gpio_set_mode (c -> sda_gpio , MGOS_GPIO_MODE_OUTPUT_OD );
116
126
if (c -> debug ) {
@@ -126,22 +136,20 @@ static uint8_t mgos_i2c_read_byte(struct mgos_i2c *c,
126
136
127
137
mgos_gpio_write (c -> scl_gpio , 0 );
128
138
mgos_gpio_set_mode (c -> sda_gpio , MGOS_GPIO_MODE_INPUT );
129
- mgos_i2c_half_delay (c );
139
+ mgos_i2c_gpio_half_delay (c );
130
140
for (i = 0 ; i < 8 ; i ++ ) {
131
141
uint8_t bit ;
132
- mgos_gpio_write (c -> scl_gpio , 1 );
133
- mgos_i2c_half_delay (c );
142
+ mgos_i2c_gpio_release_scl (c );
134
143
bit = mgos_gpio_read (c -> sda_gpio );
135
144
ret_val |= (bit << (7 - i ));
136
145
mgos_gpio_write (c -> scl_gpio , 0 );
137
- mgos_i2c_half_delay (c );
146
+ mgos_i2c_gpio_half_delay (c );
138
147
}
139
148
mgos_gpio_write (c -> sda_gpio , (ack_type == I2C_ACK ? 0 : 1 ));
140
149
mgos_gpio_set_mode (c -> sda_gpio , MGOS_GPIO_MODE_OUTPUT_OD );
141
- mgos_gpio_write (c -> scl_gpio , 1 );
142
- mgos_i2c_half_delay (c );
150
+ mgos_i2c_gpio_release_scl (c );
143
151
mgos_gpio_write (c -> scl_gpio , 0 );
144
- mgos_i2c_half_delay (c );
152
+ mgos_i2c_gpio_half_delay (c );
145
153
mgos_gpio_write (c -> sda_gpio , 0 );
146
154
if (c -> debug ) {
147
155
LOG (LL_DEBUG , (" recd 0x%02x, sent %s" , ret_val ,
@@ -161,7 +169,7 @@ bool mgos_i2c_read(struct mgos_i2c *c, uint16_t addr, void *data, size_t len,
161
169
("read %d from %d, start? %d, stop? %d" , len , addr , start , stop ));
162
170
}
163
171
164
- if (start && mgos_i2c_start (c , addr , I2C_READ ) != I2C_ACK ) {
172
+ if (start && mgos_i2c_gpio_start (c , addr , I2C_READ ) != I2C_ACK ) {
165
173
goto out ;
166
174
}
167
175
@@ -188,12 +196,12 @@ bool mgos_i2c_write(struct mgos_i2c *c, uint16_t addr, const void *data,
188
196
LOG (LL_DEBUG , ("write %d to %d, stop? %d" , len , addr , stop ));
189
197
}
190
198
191
- if (start && mgos_i2c_start (c , addr , I2C_WRITE ) != I2C_ACK ) {
199
+ if (start && mgos_i2c_gpio_start (c , addr , I2C_WRITE ) != I2C_ACK ) {
192
200
goto out ;
193
201
}
194
202
195
203
while (len -- > 0 ) {
196
- if (mgos_i2c_send_byte (c , * p ++ ) != I2C_ACK ) return false;
204
+ if (mgos_i2c_gpio_send_byte (c , * p ++ ) != I2C_ACK ) return false;
197
205
}
198
206
199
207
res = true;
0 commit comments