Skip to content

Commit 0967c6b

Browse files
maribucrasbe
andcommitted
cpu/sam0_common/periph_i2c: reliably unstuck bus
On a setup I have on my desk I can reliably get the I2C bus stuck. But the current unstuck logic will not get it unstuck. Adding a full reset of the SERCOM does fix the issue, though. Co-authored-by: crasbe <[email protected]>
1 parent ccb5b8c commit 0967c6b

File tree

1 file changed

+7
-15
lines changed
  • cpu/sam0_common/periph

1 file changed

+7
-15
lines changed

cpu/sam0_common/periph/i2c.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,15 @@
2020
*/
2121

2222
#include <assert.h>
23-
#include <stdint.h>
2423
#include <errno.h>
24+
#include <stdint.h>
2525

2626
#include "busy_wait.h"
27-
#include "cpu.h"
28-
#include "board.h"
2927
#include "mutex.h"
3028
#include "periph_conf.h"
3129
#include "periph/gpio.h"
3230
#include "periph/i2c.h"
3331

34-
#include "sched.h"
35-
#include "thread.h"
36-
3732
#define ENABLE_DEBUG 0
3833
#include "debug.h"
3934

@@ -112,7 +107,10 @@ static bool _check_and_unblock_bus(i2c_t dev_id, bool initialized)
112107
{
113108
const i2c_conf_t *dev_conf = &i2c_config[dev_id];
114109

115-
/* reconfigure pins to gpio for testing */
110+
/* do a full reset of the SERCOM */
111+
if (initialized) {
112+
bus(dev_id)->CTRLA.reg = SERCOM_I2CM_CTRLA_SWRST;
113+
}
116114
gpio_disable_mux(dev_conf->sda_pin);
117115
gpio_disable_mux(dev_conf->scl_pin);
118116
gpio_init(dev_conf->sda_pin, GPIO_IN);
@@ -153,13 +151,7 @@ static bool _check_and_unblock_bus(i2c_t dev_id, bool initialized)
153151
}
154152

155153
if (initialized) {
156-
/* reconfigure pins for i2c */
157-
gpio_init_mux(dev_conf->scl_pin, dev_conf->mux);
158-
gpio_init_mux(dev_conf->sda_pin, dev_conf->mux);
159-
160-
/* reset bus state */
161-
dev_conf->dev->STATUS.reg = BUSSTATE_IDLE;
162-
_syncbusy(dev_conf->dev);
154+
i2c_init(dev_id);
163155
}
164156

165157
return success;
@@ -168,7 +160,7 @@ static bool _check_and_unblock_bus(i2c_t dev_id, bool initialized)
168160
void i2c_init(i2c_t dev)
169161
{
170162
uint32_t timeout_counter = 0;
171-
int32_t tmp_baud;
163+
uint32_t tmp_baud;
172164

173165
assert(dev < I2C_NUMOF);
174166

0 commit comments

Comments
 (0)