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"
3435#include "supervisor/shared/translate.h"
3536#include "common-hal/microcontroller/Pin.h"
3637
38+ STATIC bool reserved_i2c [3 ];
39+
3740void 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
4156void 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}
0 commit comments