@@ -7,35 +7,48 @@ extern "C" {
7
7
#include " Wire.h"
8
8
9
9
#define I2C_DEFAULT_FREQ 100000
10
+ #define MAX_I2C_INSTANCES 10
10
11
11
- TwoWire::TwoWire (cyhal_gpio_t sda, cyhal_gpio_t scl) : sda_pin(sda), scl_pin(scl) {
12
+ TwoWire *TwoWire::instances[MAX_I2C_INSTANCES] = {nullptr };
13
+ cyhal_i2c_t TwoWire::i2c_objs[MAX_I2C_INSTANCES];
14
+
15
+ TwoWire::TwoWire (cyhal_gpio_t sda, cyhal_gpio_t scl, uint8_t instance) : sda_pin(sda), scl_pin(scl), instance(instance) {
16
+ if (instance < MAX_I2C_INSTANCES) {
17
+ instances[instance] = this ;
18
+ }
12
19
}
13
20
14
21
void TwoWire::_begin () {
15
-
16
22
rxBufferIndex = 0 ;
17
23
rxBufferLength = 0 ;
18
24
19
25
txBufferIndex = 0 ;
20
26
txBufferLength = 0 ;
21
27
22
28
if (is_master) {
23
- i2c_config= {
24
- .is_slave = is_master ? false : true ,
25
- 0 ,
29
+ i2c_config = {
30
+ .is_slave = CYHAL_I2C_MODE_MASTER ,
31
+ . address = 0 ,
26
32
.frequencyhal_hz = I2C_DEFAULT_FREQ
27
33
};
28
- }
29
- else {
34
+ } else {
30
35
i2c_config = {
31
- .is_slave = is_master ? false : true ,
32
- slave_address,
36
+ .is_slave = CYHAL_I2C_MODE_SLAVE ,
37
+ . address = slave_address,
33
38
.frequencyhal_hz = I2C_DEFAULT_FREQ
34
39
};
35
40
}
36
- cyhal_i2c_init (&i2c_obj, sda_pin, scl_pin, NULL );
37
- cyhal_i2c_configure (&i2c_obj, &i2c_config);
38
- cyhal_i2c_register_callback (&i2c_obj, i2c_event_handler, this );
41
+
42
+ cyhal_i2c_init (&i2c_objs[instance], sda_pin, scl_pin, NULL );
43
+ cyhal_i2c_configure (&i2c_objs[instance], &i2c_config);
44
+
45
+ if (!is_master) {
46
+ // Configure the read and write buffers for the I2C slave
47
+ cyhal_i2c_slave_config_read_buffer (&i2c_objs[instance], rxBuffer, BUFFER_LENGTH);
48
+ cyhal_i2c_slave_config_write_buffer (&i2c_objs[instance], txBuffer, BUFFER_LENGTH);
49
+ }
50
+
51
+ cyhal_i2c_register_callback (&i2c_objs[instance], i2c_event_handler, this );
39
52
}
40
53
41
54
void TwoWire::begin () {
@@ -60,57 +73,123 @@ void TwoWire::begin(uint8_t address) {
60
73
}
61
74
62
75
void TwoWire::end () {
63
- cyhal_i2c_free (&i2c_obj );
76
+ cyhal_i2c_free (&i2c_objs[instance] );
64
77
}
65
78
66
79
void TwoWire::setClock (uint32_t freq) {
67
- if (is_master) {
80
+ if (is_master) {
68
81
i2c_config = {
69
82
.is_slave = false ,
70
- 0 ,
83
+ . address = 0 ,
71
84
.frequencyhal_hz = freq
72
85
};
73
- }
74
- else {
86
+ } else {
75
87
i2c_config = {
76
88
.is_slave = true ,
77
- slave_address,
89
+ . address = slave_address,
78
90
.frequencyhal_hz = freq
79
91
};
80
92
}
81
- cyhal_i2c_configure (&i2c_obj , &i2c_config);
93
+ cyhal_i2c_configure (&i2c_objs[instance] , &i2c_config);
82
94
}
83
95
84
- void TwoWire:: beginTransmission(uint8_t address) {
96
+ void TwoWire::beginTransmission (uint8_t address) {
85
97
txAddress = address;
86
98
txBufferIndex = 0 ;
87
99
txBufferLength = 0 ;
88
100
}
89
101
90
102
uint8_t TwoWire::endTransmission (bool sendStop) {
91
- cy_rslt_t result = cyhal_i2c_master_write (&i2c_obj, slave_address, txBuffer, txBufferLength, timeout, sendStop);
92
-
93
- txBufferIndex = 0 ;
94
- txBufferLength = 0 ;
103
+ cy_rslt_t result;
104
+ if (txBufferLength == 0 ) {
105
+ result = cyhal_i2c_master_write (&i2c_objs[instance], txAddress, txBuffer, 0 , timeout, sendStop);
106
+ if (result != 0xAA2004 && result != 0xAA2005 ) {
107
+ return 1 ;
108
+ } else {
109
+ return 0 ;
110
+ }
111
+ } else {
112
+ result = cyhal_i2c_master_write (&i2c_objs[instance], txAddress, txBuffer, txBufferLength, timeout, sendStop);
113
+ txBufferIndex = 0 ;
114
+ txBufferLength = 0 ;
115
+ }
95
116
96
- return (result == CY_RSLT_SUCCESS) ? 0 : 1 ; // Return 0 on success, 1 on failure
117
+ if (result != CY_RSLT_SUCCESS) {
118
+ // Handle specific error codes
119
+ switch (result) {
120
+ case 0xAA2004 :
121
+ Serial.println (" Error: No device attached to SDA/SCL, but they are pulled-up." );
122
+ break ;
123
+ case 0xAA2003 :
124
+ Serial.println (" Error: No device attached to SDA/SCL, and they are not pulled-up." );
125
+ break ;
126
+ case CYHAL_I2C_RSLT_ERR_INVALID_PIN:
127
+ Serial.println (" Error: Invalid pin." );
128
+ break ;
129
+ case CYHAL_I2C_RSLT_ERR_CAN_NOT_REACH_DR:
130
+ Serial.println (" Error: Cannot reach desired data rate." );
131
+ break ;
132
+ case CYHAL_I2C_RSLT_ERR_INVALID_ADDRESS_SIZE:
133
+ Serial.println (" Error: Invalid address size." );
134
+ break ;
135
+ case CYHAL_I2C_RSLT_ERR_TX_RX_BUFFERS_ARE_EMPTY:
136
+ Serial.println (" Error: TX/RX buffers are empty." );
137
+ break ;
138
+ case CYHAL_I2C_RSLT_ERR_PREVIOUS_ASYNCH_PENDING:
139
+ Serial.println (" Error: Previous async operation is pending." );
140
+ break ;
141
+ case CYHAL_I2C_RSLT_ERR_PM_CALLBACK:
142
+ Serial.println (" Error: Failed to register I2C PM callback." );
143
+ break ;
144
+ case CYHAL_I2C_RSLT_ERR_ABORT_ASYNC_TIMEOUT:
145
+ Serial.println (" Error: Abort async operation timed out." );
146
+ break ;
147
+ case CYHAL_I2C_RSLT_ERR_BAD_ARGUMENT:
148
+ Serial.println (" Error: Bad argument provided." );
149
+ break ;
150
+ case CYHAL_I2C_RSLT_ERR_UNSUPPORTED:
151
+ Serial.println (" Error: Unsupported by this device." );
152
+ break ;
153
+ case CYHAL_I2C_RSLT_ERR_NO_ACK:
154
+ Serial.println (" Error: No ACK received." );
155
+ break ;
156
+ case CYHAL_I2C_RSLT_ERR_CMD_ERROR:
157
+ Serial.println (" Error: Command error." );
158
+ break ;
159
+ case CYHAL_I2C_RSLT_ERR_BUFFERS_NULL_PTR:
160
+ Serial.println (" Error: RX or TX buffer is not initialized." );
161
+ break ;
162
+ case CYHAL_I2C_RSLT_WARN_TIMEOUT:
163
+ Serial.println (" Warning: Timeout." );
164
+ break ;
165
+ case CYHAL_I2C_RSLT_WARN_DEVICE_BUSY:
166
+ Serial.println (" Warning: Device busy." );
167
+ break ;
168
+ default :
169
+ Serial.print (" I2C transfer failed with return code: " );
170
+ Serial.println (result, HEX);
171
+ break ;
172
+ }
173
+ return 1 ; // Return 1 on failure
174
+ }
175
+
176
+ return 0 ; // Return 0 on success
97
177
}
98
178
99
179
uint8_t TwoWire::endTransmission (void ) {
100
180
return endTransmission (true );
101
181
}
102
182
103
183
size_t TwoWire::requestFrom (uint8_t address, size_t quantity, bool stopBit) {
104
- if (quantity > BUFFER_LENGTH){
184
+ if (quantity > BUFFER_LENGTH) {
105
185
quantity = BUFFER_LENGTH;
106
186
}
107
- cy_rslt_t result = cyhal_i2c_master_read (&i2c_obj , address, rxBuffer, quantity, timeout, stopBit);
108
- if (result == CY_RSLT_SUCCESS){
187
+ cy_rslt_t result = cyhal_i2c_master_read (&i2c_objs[instance] , address, rxBuffer, quantity, timeout, stopBit);
188
+ if (result == CY_RSLT_SUCCESS) {
109
189
rxBufferIndex = 0 ;
110
190
rxBufferLength = quantity;
111
191
return quantity;
112
- }
113
- else {
192
+ } else {
114
193
return 0 ; // Return 0 on failure of read operation
115
194
}
116
195
}
@@ -120,74 +199,70 @@ size_t TwoWire::requestFrom(uint8_t address, size_t len) {
120
199
}
121
200
122
201
size_t TwoWire::write (uint8_t data) {
123
- /* Check if buffer is full */
124
- if (txBufferLength >= BUFFER_LENGTH){
125
- return 0 ;
126
- }
202
+ /* Check if buffer is full */
203
+ if (txBufferLength >= BUFFER_LENGTH) {
204
+ return 0 ;
205
+ }
127
206
128
- /* Put byte in txBuffer */
129
- txBuffer[txBufferIndex] = data;
130
- txBufferIndex++;
207
+ /* Put byte in txBuffer */
208
+ txBuffer[txBufferIndex] = data;
209
+ txBufferIndex++;
131
210
132
- /* Update buffer length */
133
- txBufferLength = txBufferIndex;
134
-
135
- return 1 ;
211
+ /* Update buffer length */
212
+ txBufferLength = txBufferIndex;
213
+
214
+ return 1 ;
136
215
}
137
216
138
217
size_t TwoWire::write (const uint8_t * data, size_t quantity) {
139
- for (size_t i = 0 ; i < quantity; i++){
140
- write (*(data + i));
141
- }
218
+ for (size_t i = 0 ; i < quantity; i++) {
219
+ write (*(data + i));
220
+ }
142
221
143
- return quantity;
222
+ return quantity;
144
223
}
145
224
146
225
int TwoWire::available (void ) {
147
-
148
226
return rxBufferLength - rxBufferIndex;
149
227
}
150
228
151
229
int TwoWire::read (void ) {
152
- if (rxBufferIndex < rxBufferLength)
153
- {
230
+ if (rxBufferIndex < rxBufferLength) {
154
231
return rxBuffer[rxBufferIndex++];
155
232
}
156
233
return -1 ;
157
234
}
158
235
159
236
int TwoWire::peek (void ) {
160
- if (rxBufferIndex < rxBufferLength)
161
- {
237
+ if (rxBufferIndex < rxBufferLength) {
162
238
return rxBuffer[rxBufferIndex];
163
239
}
164
240
return -1 ;
165
241
}
166
242
167
243
void TwoWire::onReceive (void (*function)(int )) {
168
- user_onReceive = function;
169
- cyhal_i2c_enable_event (&i2c_obj, CYHAL_I2C_SLAVE_READ_EVENT , 7 , true );
244
+ user_onReceive = function;
245
+ cyhal_i2c_enable_event (&i2c_objs[instance], CYHAL_I2C_SLAVE_WRITE_EVENT , 7 , true );
170
246
}
171
247
172
248
void TwoWire::onRequest (void (*function)(void )) {
173
249
user_onRequest = function;
174
- cyhal_i2c_enable_event (&i2c_obj, CYHAL_I2C_SLAVE_WRITE_EVENT , 7 , true );
250
+ cyhal_i2c_enable_event (&i2c_objs[instance], CYHAL_I2C_SLAVE_READ_EVENT , 7 , true );
175
251
}
176
252
177
253
void TwoWire::i2c_event_handler (void *callback_arg, cyhal_i2c_event_t event) {
178
254
TwoWire *instance = static_cast <TwoWire*>(callback_arg);
179
- if (event == CYHAL_I2C_SLAVE_READ_EVENT && instance->user_onReceive ) {
255
+ if (event == CYHAL_I2C_SLAVE_WRITE_EVENT && instance->user_onReceive ) {
180
256
instance->user_onReceive (instance->available ());
181
- } else if (event == CYHAL_I2C_SLAVE_WRITE_EVENT && instance->user_onRequest ) {
257
+ } else if (event == CYHAL_I2C_SLAVE_READ_EVENT && instance->user_onRequest ) {
182
258
instance->user_onRequest ();
183
259
}
184
260
}
185
261
186
262
#if I2C_HOWNMANY > 0
187
- TwoWire Wire = TwoWire(I2C1_SDA_PIN, I2C1_SCL_PIN);
263
+ TwoWire Wire = TwoWire(I2C1_SDA_PIN, I2C1_SCL_PIN, 0 );
188
264
#endif
189
265
190
266
#if I2C_HOWNMANY > 1
191
- TwoWire Wire1 = TwoWire(I2C2_SDA_PIN, I2C2_SCL_PIN);
192
- #endif
193
-
267
+ TwoWire Wire1 = TwoWire(I2C2_SDA_PIN, I2C2_SCL_PIN, 1 );
268
+ #endif
0 commit comments