Skip to content

Commit ef15ebe

Browse files
committed
Repeated initialization protection, cleanup
1 parent 18c5be8 commit ef15ebe

6 files changed

Lines changed: 84 additions & 166 deletions

File tree

ports/stm32f4/common-hal/busio/I2C.c

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525
* THE SOFTWARE.
2626
*/
27+
#include <stdbool.h>
2728

2829
#include "shared-bindings/busio/I2C.h"
2930
#include "py/mperrno.h"
@@ -34,8 +35,22 @@
3435
#include "supervisor/shared/translate.h"
3536
#include "common-hal/microcontroller/Pin.h"
3637

38+
STATIC bool reserved_i2c[3];
39+
3740
void i2c_reset(void) {
38-
//TODO: implement something better than eratta workaround.
41+
//Note: I2Cs are also forcibly reset in construct, due to silicon error
42+
#ifdef I2C1
43+
reserved_i2c[0] = false;
44+
__HAL_RCC_I2C1_CLK_DISABLE();
45+
#endif
46+
#ifdef I2C2
47+
reserved_i2c[1] = false;
48+
__HAL_RCC_I2C2_CLK_DISABLE();
49+
#endif
50+
#ifdef I2C3
51+
reserved_i2c[3] = false;
52+
__HAL_RCC_I2C3_CLK_DISABLE();
53+
#endif
3954
}
4055

4156
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
@@ -47,12 +62,12 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
4762
uint8_t sda_len = sizeof(mcu_i2c_sda_list)/sizeof(*mcu_i2c_sda_list);
4863
uint8_t scl_len = sizeof(mcu_i2c_scl_list)/sizeof(*mcu_i2c_scl_list);
4964
for(uint i=0; i<sda_len;i++) {
50-
if (mcu_i2c_sda_list[i]->pin == sda) {
65+
if (mcu_i2c_sda_list[i].pin == sda) {
5166
for(uint j=0; j<scl_len;j++) {
52-
if ((mcu_i2c_scl_list[j]->pin == scl)
53-
&& (mcu_i2c_scl_list[j]->i2c_index == mcu_i2c_sda_list[i]->i2c_index)) {
54-
self->scl = mcu_i2c_scl_list[j];
55-
self->sda = mcu_i2c_sda_list[i];
67+
if ((mcu_i2c_scl_list[j].pin == scl)
68+
&& (mcu_i2c_scl_list[j].i2c_index == mcu_i2c_sda_list[i].i2c_index)) {
69+
self->scl = &mcu_i2c_scl_list[j];
70+
self->sda = &mcu_i2c_sda_list[i];
5671
break;
5772
}
5873
}
@@ -66,6 +81,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
6681
mp_raise_RuntimeError(translate("Invalid I2C pin selection"));
6782
}
6883

84+
if(reserved_i2c[self->sda->i2c_index-1]) {
85+
mp_raise_RuntimeError(translate("Hardware busy, try alternative pins"));
86+
}
87+
6988
//Start GPIO for each pin
7089
GPIO_InitTypeDef GPIO_InitStruct = {0};
7190
GPIO_InitStruct.Pin = pin_mask(sda->number);
@@ -84,7 +103,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
84103

85104
//Fix for HAL error caused by soft reboot GPIO init SDA pin voltage drop. See Eratta.
86105
//Must be in this exact spot or I2C will get stuck in infinite loop.
87-
//TODO: delet
106+
//TODO: See git issue #2172
88107
#ifdef I2C1
89108
__HAL_RCC_I2C1_FORCE_RESET();
90109
HAL_Delay(2);
@@ -101,14 +120,24 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
101120
__HAL_RCC_I2C3_RELEASE_RESET();
102121
#endif
103122

123+
//Keep separate so above hack can be cleanly replaced
104124
#ifdef I2C1
105-
if(I2Cx==I2C1) __HAL_RCC_I2C1_CLK_ENABLE();
125+
if(I2Cx==I2C1) {
126+
reserved_i2c[0] = true;
127+
__HAL_RCC_I2C1_CLK_ENABLE();
128+
}
106129
#endif
107130
#ifdef I2C2
108-
if(I2Cx==I2C2) __HAL_RCC_I2C2_CLK_ENABLE();
131+
if(I2Cx==I2C2) {
132+
reserved_i2c[1] = true;
133+
__HAL_RCC_I2C2_CLK_ENABLE();
134+
}
109135
#endif
110136
#ifdef I2C3
111-
if(I2Cx==I2C3) __HAL_RCC_I2C3_CLK_ENABLE();
137+
if(I2Cx==I2C3) {
138+
reserved_i2c[2] = true;
139+
__HAL_RCC_I2C3_CLK_ENABLE();
140+
}
112141
#endif
113142

114143
self->handle.Instance = I2Cx;
@@ -122,9 +151,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
122151
self->handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
123152
if(HAL_I2C_Init(&(self->handle)) != HAL_OK) {
124153
mp_raise_RuntimeError(translate("I2C Init Error"));
125-
} else {
126-
//TODO: remove post testing
127-
mp_printf(&mp_plat_print, "I2C INIT OK\n");
128154
}
129155
claim_pin(sda);
130156
claim_pin(scl);
@@ -139,16 +165,25 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
139165
return;
140166
}
141167
#ifdef I2C1
142-
if(self->handle.Instance==I2C1) __HAL_RCC_I2C1_CLK_DISABLE();
168+
if(self->handle.Instance==I2C1) {
169+
reserved_i2c[0] = 0;
170+
__HAL_RCC_I2C1_CLK_DISABLE();
171+
}
143172
#endif
144173
#ifdef I2C2
145-
if(self->handle.Instance==I2C2) __HAL_RCC_I2C2_CLK_DISABLE();
174+
if(self->handle.Instance==I2C2) {
175+
reserved_i2c[1] = 0;
176+
__HAL_RCC_I2C2_CLK_DISABLE();
177+
}
146178
#endif
147179
#ifdef I2C3
148-
if(self->handle.Instance==I2C3) __HAL_RCC_I2C3_CLK_DISABLE();
180+
if(self->handle.Instance==I2C3) {
181+
reserved_i2c[3] = 0;
182+
__HAL_RCC_I2C3_CLK_DISABLE();
183+
}
149184
#endif
150-
HAL_GPIO_DeInit(pin_port(self->sda->pin->port), pin_mask(self->sda->pin->number));
151-
HAL_GPIO_DeInit(pin_port(self->scl->pin->port), pin_mask(self->scl->pin->number));
185+
reset_pin_number(self->sda->pin->port,self->sda->pin->number);
186+
reset_pin_number(self->scl->pin->port,self->scl->pin->number);
152187
self->sda = mp_const_none;
153188
self->scl = mp_const_none;
154189
}

ports/stm32f4/peripherals/stm32f4/periph.h

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,51 +33,6 @@
3333
#include "stm32f4xx_hal.h"
3434
#include "stm32f4/pins.h"
3535

36-
// #define PA 0
37-
// #define PB 1
38-
// #define PC 2
39-
// #define PD 3
40-
// #define PE 4
41-
// #define PF 5
42-
// #define PG 6
43-
// #define PH 7
44-
// #define PI 8
45-
// #define PJ 9
46-
// #define PK 10
47-
48-
// I2C
49-
50-
// Numerical Version
51-
52-
/*
53-
typedef struct {
54-
mp_obj_base_t base;
55-
uint8_t i2c_index:3; // Index of the I2C unit
56-
uint8_t alt_index:4; // Alt index is arbitrary, it just lists additional pin options
57-
uint8_t sda_pin_port:4;
58-
uint8_t sda_pin_number:4;
59-
uint8_t scl_pin_port:4;
60-
uint8_t scl_pin_number:4;
61-
} mcu_i2c_periph_obj_t;
62-
63-
#define SDA(port, number) \
64-
.sda_pin_port = port, \
65-
.sda_pin_number = number,
66-
67-
#define SCL(port, number) \
68-
.scl_pin_port = port, \
69-
.scl_pin_number = number
70-
71-
#define I2C(index, alt, sda, scl) \
72-
{ \
73-
{ &prefix_fields }, \
74-
.i2c_index = index, \
75-
.alt_index = alt, \
76-
sda \
77-
scl \
78-
}
79-
*/
80-
8136
// Address Version
8237
typedef struct {
8338
uint8_t i2c_index:4; // Index of the I2C unit (1 to 3)

ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,46 +29,24 @@
2929
#include "stm32f4/pins.h"
3030
#include "stm32f4/periph.h"
3131

32-
//const mcu_i2c_periph_obj_t periph_I2C1_0 = I2C(1, 0, SDA(PB,7), SCL(PB,6));
33-
//const mcu_i2c_periph_obj_t periph_I2C1_1 = I2C(1, 1, SDA(PB,9), SCL(PB,8));
34-
//const mcu_i2c_periph_obj_t periph_I2C2 = I2C(1, NO_ALT, SDA(PB,11), SCL(PB,10));
35-
//const mcu_i2c_periph_obj_t periph_I2C3 = I2C(1, NO_ALT, SDA(PB,9), SCL(PB,8));
36-
3732
// I2C
3833

3934
I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
4035

41-
//SDA Pins
42-
const mcu_i2c_sda_obj_t per_SDA_1B07 = I2C_SDA(1, 4, &pin_PB07);
43-
const mcu_i2c_sda_obj_t per_SDA_1B09 = I2C_SDA(1, 4, &pin_PB09);
44-
// const mcu_i2c_sda_obj_t per_SDA_2B11 = I2C_SDA(2, 4, &pin_PB11); //not on LQFP100
45-
const mcu_i2c_sda_obj_t per_SDA_2B09 = I2C_SDA(2, 9, &pin_PB09);
46-
const mcu_i2c_sda_obj_t per_SDA_2B03 = I2C_SDA(2, 9, &pin_PB03);
47-
const mcu_i2c_sda_obj_t per_SDA_3C09 = I2C_SDA(3, 4, &pin_PC09);
48-
const mcu_i2c_sda_obj_t per_SDA_3B04 = I2C_SDA(3, 9, &pin_PB04);
49-
const mcu_i2c_sda_obj_t per_SDA_3B08 = I2C_SDA(3, 9, &pin_PB08);
50-
51-
//SCL Pins
52-
const mcu_i2c_scl_obj_t per_SCL_1B06 = I2C_SCL(1, 4, &pin_PB06);
53-
const mcu_i2c_scl_obj_t per_SCL_1B08 = I2C_SCL(1, 4, &pin_PB08);
54-
const mcu_i2c_scl_obj_t per_SCL_2B10 = I2C_SCL(2, 4, &pin_PB10);
55-
const mcu_i2c_scl_obj_t per_SCL_3B08 = I2C_SCL(3, 4, &pin_PA08);
56-
57-
const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[7] = {
58-
&per_SDA_1B07,
59-
&per_SDA_1B09,
60-
&per_SDA_2B09,
61-
&per_SDA_2B03,
62-
&per_SDA_3C09,
63-
&per_SDA_3B04,
64-
&per_SDA_3B08
36+
const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7] = {
37+
I2C_SDA(1, 4, &pin_PB07),
38+
I2C_SDA(1, 4, &pin_PB09),
39+
I2C_SDA(2, 9, &pin_PB09),
40+
I2C_SDA(2, 9, &pin_PB03),
41+
I2C_SDA(3, 4, &pin_PC09),
42+
I2C_SDA(3, 9, &pin_PB04),
43+
I2C_SDA(3, 9, &pin_PB08)
6544
};
6645

67-
const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4] = {
68-
&per_SCL_1B06,
69-
&per_SCL_1B08,
70-
&per_SCL_2B10,
71-
&per_SCL_3B08
46+
const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
47+
I2C_SCL(1, 4, &pin_PB06),
48+
I2C_SCL(1, 4, &pin_PB08),
49+
I2C_SCL(2, 4, &pin_PB10),
50+
I2C_SCL(3, 4, &pin_PA08)
7251
};
73-
7452
//SPI, UART, Etc

ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,7 @@
3030
//I2C
3131
extern I2C_TypeDef * mcu_i2c_banks[3];
3232

33-
extern const mcu_i2c_sda_obj_t per_SDA_1B07;
34-
extern const mcu_i2c_sda_obj_t per_SDA_1B09;
35-
//extern const mcu_i2c_sda_obj_t per_SDA_2B11;
36-
extern const mcu_i2c_sda_obj_t per_SDA_2B09;
37-
extern const mcu_i2c_sda_obj_t per_SDA_2B03;
38-
extern const mcu_i2c_sda_obj_t per_SDA_3C09;
39-
extern const mcu_i2c_sda_obj_t per_SDA_3B04;
40-
extern const mcu_i2c_sda_obj_t per_SDA_3B08;
41-
42-
extern const mcu_i2c_scl_obj_t per_SCL_1B06;
43-
extern const mcu_i2c_scl_obj_t per_SCL_1B08;
44-
extern const mcu_i2c_scl_obj_t per_SCL_2B10;
45-
extern const mcu_i2c_scl_obj_t per_SCL_3B08;
46-
47-
extern const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[7];
48-
extern const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4];
33+
extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[7];
34+
extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
4935

5036
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H

ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,47 +29,25 @@
2929
#include "stm32f4/pins.h"
3030
#include "stm32f4/periph.h"
3131

32-
//const mcu_i2c_periph_obj_t periph_I2C1_0 = I2C(1, 0, SDA(PB,7), SCL(PB,6));
33-
//const mcu_i2c_periph_obj_t periph_I2C1_1 = I2C(1, 1, SDA(PB,9), SCL(PB,8));
34-
//const mcu_i2c_periph_obj_t periph_I2C2 = I2C(1, NO_ALT, SDA(PB,11), SCL(PB,10));
35-
//const mcu_i2c_periph_obj_t periph_I2C3 = I2C(1, NO_ALT, SDA(PB,9), SCL(PB,8));
36-
3732
// I2C
3833

3934
I2C_TypeDef * mcu_i2c_banks[3] = {I2C1, I2C2, I2C3};
4035

41-
//SDA Pins
42-
const mcu_i2c_sda_obj_t per_SDA_1B07 = I2C_SDA(1, 4, &pin_PB07);
43-
const mcu_i2c_sda_obj_t per_SDA_1B09 = I2C_SDA(1, 4, &pin_PB09);
44-
const mcu_i2c_sda_obj_t per_SDA_2B11 = I2C_SDA(2, 4, &pin_PB11); //not on LQFP100
45-
const mcu_i2c_sda_obj_t per_SDA_2B09 = I2C_SDA(2, 9, &pin_PB09);
46-
const mcu_i2c_sda_obj_t per_SDA_2B03 = I2C_SDA(2, 9, &pin_PB03);
47-
const mcu_i2c_sda_obj_t per_SDA_3C09 = I2C_SDA(3, 4, &pin_PC09);
48-
const mcu_i2c_sda_obj_t per_SDA_3B04 = I2C_SDA(3, 9, &pin_PB04);
49-
const mcu_i2c_sda_obj_t per_SDA_3B08 = I2C_SDA(3, 9, &pin_PB08);
50-
51-
//SCL Pins
52-
const mcu_i2c_scl_obj_t per_SCL_1B06 = I2C_SCL(1, 4, &pin_PB06);
53-
const mcu_i2c_scl_obj_t per_SCL_1B08 = I2C_SCL(1, 4, &pin_PB08);
54-
const mcu_i2c_scl_obj_t per_SCL_2B10 = I2C_SCL(2, 4, &pin_PB10);
55-
const mcu_i2c_scl_obj_t per_SCL_3B08 = I2C_SCL(3, 4, &pin_PA08);
56-
57-
const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[8] = {
58-
&per_SDA_1B07,
59-
&per_SDA_1B09,
60-
&per_SDA_2B11,
61-
&per_SDA_2B09,
62-
&per_SDA_2B03,
63-
&per_SDA_3C09,
64-
&per_SDA_3B04,
65-
&per_SDA_3B08
36+
const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8] = {
37+
I2C_SDA(1, 4, &pin_PB07),
38+
I2C_SDA(1, 4, &pin_PB09),
39+
I2C_SDA(2, 4, &pin_PB11), //not on LQFP100
40+
I2C_SDA(2, 9, &pin_PB09),
41+
I2C_SDA(2, 9, &pin_PB03),
42+
I2C_SDA(3, 4, &pin_PC09),
43+
I2C_SDA(3, 9, &pin_PB04),
44+
I2C_SDA(3, 9, &pin_PB08)
6645
};
6746

68-
const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4] = {
69-
&per_SCL_1B06,
70-
&per_SCL_1B08,
71-
&per_SCL_2B10,
72-
&per_SCL_3B08
47+
const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4] = {
48+
I2C_SCL(1, 4, &pin_PB06),
49+
I2C_SCL(1, 4, &pin_PB08),
50+
I2C_SCL(2, 4, &pin_PB10),
51+
I2C_SCL(3, 4, &pin_PA08)
7352
};
74-
7553
//SPI, UART, Etc

ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,8 @@
3030
//I2C
3131
extern I2C_TypeDef * mcu_i2c_banks[3];
3232

33-
extern const mcu_i2c_sda_obj_t per_SDA_1B07;
34-
extern const mcu_i2c_sda_obj_t per_SDA_1B09;
35-
extern const mcu_i2c_sda_obj_t per_SDA_2B11;
36-
extern const mcu_i2c_sda_obj_t per_SDA_2B09;
37-
extern const mcu_i2c_sda_obj_t per_SDA_2B03;
38-
extern const mcu_i2c_sda_obj_t per_SDA_3C09;
39-
extern const mcu_i2c_sda_obj_t per_SDA_3B04;
40-
extern const mcu_i2c_sda_obj_t per_SDA_3B08;
41-
42-
extern const mcu_i2c_scl_obj_t per_SCL_1B06;
43-
extern const mcu_i2c_scl_obj_t per_SCL_1B08;
44-
extern const mcu_i2c_scl_obj_t per_SCL_2B10;
45-
extern const mcu_i2c_scl_obj_t per_SCL_3B08;
46-
47-
extern const mcu_i2c_sda_obj_t* mcu_i2c_sda_list[8];
48-
extern const mcu_i2c_scl_obj_t* mcu_i2c_scl_list[4];
33+
extern const mcu_i2c_sda_obj_t mcu_i2c_sda_list[8];
34+
extern const mcu_i2c_scl_obj_t mcu_i2c_scl_list[4];
4935

5036

5137
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H

0 commit comments

Comments
 (0)