@@ -163,6 +163,14 @@ class I2cClass {
163
163
164
164
int end () {
165
165
if (isEnabled ()) {
166
+ hal_gpio_config_t conf = {};
167
+ conf.size = sizeof (conf);
168
+ conf.version = HAL_GPIO_VERSION;
169
+ conf.mode = OUTPUT_OPEN_DRAIN_PULLUP;
170
+ conf.set_value = true ;
171
+ conf.value = 1 ;
172
+ hal_gpio_configure (sclPin_, &conf, nullptr );
173
+ hal_gpio_configure (sdaPin_, &conf, nullptr );
166
174
if (i2cInitStruct_.I2CMaster == I2C_SLAVE_MODE) {
167
175
InterruptDis (I2C0_IRQ_LP);
168
176
InterruptUnRegister (I2C0_IRQ_LP);
@@ -174,11 +182,25 @@ class I2cClass {
174
182
// RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, DISABLE);
175
183
Pinmux_Config (hal_pin_to_rtl_pin (sdaPin_), PINMUX_FUNCTION_GPIO);
176
184
Pinmux_Config (hal_pin_to_rtl_pin (sclPin_), PINMUX_FUNCTION_GPIO);
185
+ txBuffer_.reset ();
186
+ rxBuffer_.reset ();
177
187
}
178
188
return SYSTEM_ERROR_NONE;
179
189
}
180
190
181
- void reset () {
191
+ int suspend () {
192
+ CHECK_TRUE (state_ = HAL_I2C_STATE_ENABLED, SYSTEM_ERROR_INVALID_STATE);
193
+ CHECK (end ());
194
+ state_ = HAL_I2C_STATE_SUSPENDED;
195
+ return SYSTEM_ERROR_NONE;
196
+ }
197
+
198
+ int restore () {
199
+ CHECK_TRUE (state_ = HAL_I2C_STATE_SUSPENDED, SYSTEM_ERROR_INVALID_STATE);
200
+ return begin ((i2cInitStruct_.I2CMaster == I2C_MASTER_MODE) ? I2C_MODE_MASTER : I2C_MODE_SLAVE, i2cInitStruct_.I2CAckAddr );
201
+ }
202
+
203
+ int reset () {
182
204
end ();
183
205
184
206
// Just in case make sure that the pins are correctly configured (they should anyway be at this point)
@@ -188,15 +210,16 @@ class I2cClass {
188
210
conf.mode = OUTPUT_OPEN_DRAIN_PULLUP;
189
211
conf.set_value = true ;
190
212
conf.value = 1 ;
191
- hal_gpio_configure (sdaPin_, &conf, nullptr );
192
- conf.value = hal_gpio_read (sclPin_);
193
213
hal_gpio_configure (sclPin_, &conf, nullptr );
214
+ hal_gpio_configure (sdaPin_, &conf, nullptr );
215
+
216
+ // Check if slave is stretching the SCL
217
+ if (!WAIT_TIMED (HAL_I2C_DEFAULT_TIMEOUT_MS, hal_gpio_read (sclPin_) == 0 )) {
218
+ return SYSTEM_ERROR_I2C_BUS_BUSY;
219
+ }
194
220
195
221
// Generate up to 9 pulses on SCL to tell slave to release the bus
196
222
for (int i = 0 ; i < 9 ; i++) {
197
- hal_gpio_write (sdaPin_, 1 );
198
- HAL_Delay_Microseconds (50 );
199
-
200
223
if (hal_gpio_read (sdaPin_) == 0 ) {
201
224
hal_gpio_write (sclPin_, 0 );
202
225
HAL_Delay_Microseconds (50 );
@@ -222,6 +245,8 @@ class I2cClass {
222
245
223
246
hal_i2c_mode_t mode = (i2cInitStruct_.I2CMaster == I2C_MASTER_MODE) ? I2C_MODE_MASTER : I2C_MODE_SLAVE;
224
247
begin (mode, i2cInitStruct_.I2CAckAddr );
248
+ CHECK_TRUE (isEnabled (), SYSTEM_ERROR_INTERNAL);
249
+ return SYSTEM_ERROR_NONE;
225
250
}
226
251
227
252
int setSpeed (uint32_t speed) {
@@ -344,6 +369,28 @@ class I2cClass {
344
369
setAddress (transConfig_.address );
345
370
346
371
uint32_t quantity = txBuffer_.data ();
372
+ if (quantity == 0 ) {
373
+ // Clear flags
374
+ uint32_t temp = i2cDev_->IC_CLR_TX_ABRT ;
375
+ temp = i2cDev_->IC_CLR_STOP_DET ;
376
+ (void )temp;
377
+ if ((i2cDev_->IC_TX_ABRT_SOURCE & BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK)
378
+ || (i2cDev_->IC_RAW_INTR_STAT & BIT_IC_RAW_INTR_STAT_STOP_DET)) {
379
+ return SYSTEM_ERROR_I2C_ABORT;
380
+ }
381
+ // Send the slave address only
382
+ i2cDev_->IC_DATA_CMD = (transConfig_.address << 1 ) | BIT_CTRL_IC_DATA_CMD_NULLDATA | BIT_CTRL_IC_DATA_CMD_STOP;
383
+ // If slave is not detected, the STOP_DET bit won't be set, and the TX_ABRT is set instead.
384
+ if (!WAIT_TIMED (transConfig_.timeout_ms , ((i2cDev_->IC_TX_ABRT_SOURCE & BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK) == 0 )
385
+ && ((i2cDev_->IC_RAW_INTR_STAT & BIT_IC_RAW_INTR_STAT_STOP_DET) == 0 ))) {
386
+ return SYSTEM_ERROR_I2C_TX_ADDR_TIMEOUT;
387
+ }
388
+ if (i2cDev_->IC_TX_ABRT_SOURCE & BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK) {
389
+ return SYSTEM_ERROR_I2C_ABORT;
390
+ }
391
+ return SYSTEM_ERROR_NONE;
392
+ }
393
+
347
394
for (uint32_t i = 0 ; i < quantity; i++) {
348
395
if (!WAIT_TIMED (transConfig_.timeout_ms , I2C_CheckFlagState (i2cDev_, BIT_IC_STATUS_TFNF) == 0 )) {
349
396
reset ();
@@ -356,10 +403,10 @@ class I2cClass {
356
403
if (i >= quantity - 1 ) {
357
404
if (stop) {
358
405
// Generate stop signal
359
- i2cDev_->IC_DATA_CMD = data | ( 1 << 9 ) ;
406
+ i2cDev_->IC_DATA_CMD = data | BIT_CTRL_IC_DATA_CMD_STOP ;
360
407
} else {
361
408
// Generate restart signal
362
- i2cDev_->IC_DATA_CMD = data | ( 1 << 10 ) ;
409
+ i2cDev_->IC_DATA_CMD = data | BIT_CTRL_IC_DATA_CMD_RESTART ;
363
410
}
364
411
} else {
365
412
// The address will be sent before sending the first data byte
@@ -684,11 +731,10 @@ void hal_i2c_enable_dma_mode(hal_i2c_interface_t i2c, bool enable, void* reserve
684
731
// use DMA to send data by default
685
732
}
686
733
687
- uint8_t hal_i2c_reset (hal_i2c_interface_t i2c, uint32_t reserved, void * reserved1) {
688
- auto instance = CHECK_TRUE_RETURN (I2cClass::getInstance (i2c), 1 );
734
+ int hal_i2c_reset (hal_i2c_interface_t i2c, uint32_t reserved, void * reserved1) {
735
+ auto instance = CHECK_TRUE_RETURN (I2cClass::getInstance (i2c), SYSTEM_ERROR_NOT_FOUND );
689
736
I2cLock lk (instance);
690
- instance->reset ();
691
- return 0 ;
737
+ return instance->reset ();
692
738
}
693
739
694
740
int32_t hal_i2c_lock (hal_i2c_interface_t i2c, void * reserved) {
@@ -702,12 +748,12 @@ int32_t hal_i2c_unlock(hal_i2c_interface_t i2c, void* reserved) {
702
748
}
703
749
704
750
int hal_i2c_sleep (hal_i2c_interface_t i2c, bool sleep, void * reserved) {
705
- // auto instance = CHECK_TRUE_RETURN(I2cClass::getInstance(i2c), SYSTEM_ERROR_NOT_FOUND);
706
- // I2cLock lk(i2c );
707
- // if (sleep) {
708
- // Suspend I2C
709
- // } else {
710
- // Restore I2C
711
- // }
751
+ auto instance = CHECK_TRUE_RETURN (I2cClass::getInstance (i2c), SYSTEM_ERROR_NOT_FOUND);
752
+ I2cLock lk (instance );
753
+ if (sleep ) {
754
+ return instance-> suspend ();
755
+ } else {
756
+ return instance-> restore ();
757
+ }
712
758
return SYSTEM_ERROR_NONE;
713
759
}
0 commit comments