3737#include "i2c.h"
3838#include MICROPY_HAL_H
3939
40- #if !defined(STM32F7 )
41- // The STM32F7 has Timing, where the F4 has ClockSpeed and DutyCycle, so we
42- // need to figure that out before we can enable i2c
40+ #if !defined(MICROPY_HW_I2C_BAUDRATE_DEFAULT )
41+ #define MICROPY_HW_I2C_BAUDRATE_DEFAULT 400000
42+ #endif
43+
44+ #if !defined(MICROPY_HW_I2C_BAUDRATE_MAX )
45+ #define MICROPY_HW_I2C_BAUDRATE_MAX 400000
46+ #endif
47+
48+ #if !defined(I2C_NOSTRETCH_DISABLE )
49+ // Assumes that the F7 firmware is newer, so the F4 firmware will eventually
50+ // catchup. I2C_NOSTRETCH_DISABLED was renamed to I2C_NOSTRETCH_DISABLE
51+ // in the F7 so we use the F7 constant and provide a backwards compatabilty
52+ // #define here.
53+ #define I2C_NOSTRETCH_DISABLE I2C_NOSTRETCH_DISABLED
54+ #endif
4355
4456/// \moduleref pyb
4557/// \class I2C - a two-wire serial protocol
@@ -138,6 +150,50 @@ STATIC const pyb_i2c_obj_t pyb_i2c_obj[] = {
138150 #endif
139151};
140152
153+ #if defined(MICROPY_HW_I2C_BAUDRATE_TIMING )
154+ // The STM32F0, F3, and F7 use a TIMINGR register rather than ClockSpeed and
155+ // DutyCycle.
156+
157+ STATIC const struct {
158+ uint32_t baudrate ;
159+ uint32_t timing ;
160+ } pyb_i2c_baudrate_timing [ ] = MICROPY_HW_I2C_BAUDRATE_TIMING ;
161+
162+ #define NUM_BAUDRATE_TIMINGS MP_ARRAY_SIZE(pyb_i2c_baudrate_timing)
163+
164+ STATIC void i2c_set_baudrate (I2C_InitTypeDef * init , uint32_t baudrate ) {
165+ for (int i = 0 ; i < NUM_BAUDRATE_TIMINGS ; i ++ ) {
166+ if (pyb_i2c_baudrate_timing [i ].baudrate == baudrate ) {
167+ init -> Timing = pyb_i2c_baudrate_timing [i ].timing ;
168+ return ;
169+ }
170+ }
171+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError ,
172+ "Unsupported I2C baudrate: %lu" , baudrate ));
173+ }
174+
175+ STATIC uint32_t i2c_get_baudrate (I2C_InitTypeDef * init ) {
176+ for (int i = 0 ; i < NUM_BAUDRATE_TIMINGS ; i ++ ) {
177+ if (pyb_i2c_baudrate_timing [i ].timing == init -> Timing ) {
178+ return pyb_i2c_baudrate_timing [i ].baudrate ;
179+ }
180+ }
181+ return 0 ;
182+ }
183+
184+ #else
185+
186+ STATIC void i2c_set_baudrate (I2C_InitTypeDef * init , uint32_t baudrate ) {
187+ init -> ClockSpeed = baudrate ;
188+ init -> DutyCycle = I2C_DUTYCYCLE_16_9 ;
189+ }
190+
191+ STATIC uint32_t i2c_get_baudrate (I2C_InitTypeDef * init ) {
192+ return init -> ClockSpeed ;
193+ }
194+
195+ #endif // MICROPY_HW_I2C_BAUDRATE_TIMING
196+
141197void i2c_init0 (void ) {
142198 // reset the I2C1 handles
143199 #if defined(MICROPY_HW_I2C1_SCL )
@@ -276,7 +332,7 @@ STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
276332 mp_printf (print , "I2C(%u)" , i2c_num );
277333 } else {
278334 if (in_master_mode (self )) {
279- mp_printf (print , "I2C(%u, I2C.MASTER, baudrate=%u)" , i2c_num , self -> i2c -> Init . ClockSpeed );
335+ mp_printf (print , "I2C(%u, I2C.MASTER, baudrate=%u)" , i2c_num , i2c_get_baudrate ( & self -> i2c -> Init ) );
280336 } else {
281337 mp_printf (print , "I2C(%u, I2C.SLAVE, addr=0x%02x)" , i2c_num , (self -> i2c -> Instance -> OAR1 >> 1 ) & 0x7f );
282338 }
@@ -295,7 +351,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args,
295351 static const mp_arg_t allowed_args [] = {
296352 { MP_QSTR_mode , MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 0 } },
297353 { MP_QSTR_addr , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0x12 } },
298- { MP_QSTR_baudrate , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 400000 } },
354+ { MP_QSTR_baudrate , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = MICROPY_HW_I2C_BAUDRATE_DEFAULT } },
299355 { MP_QSTR_gencall , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
300356 };
301357
@@ -313,13 +369,13 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args,
313369 init -> OwnAddress1 = (args [1 ].u_int << 1 ) & 0xfe ;
314370 }
315371
372+ i2c_set_baudrate (init , MIN (args [2 ].u_int , MICROPY_HW_I2C_BAUDRATE_MAX ));
316373 init -> AddressingMode = I2C_ADDRESSINGMODE_7BIT ;
317- init -> ClockSpeed = MIN (args [2 ].u_int , 400000 );
318374 init -> DualAddressMode = I2C_DUALADDRESS_DISABLED ;
319- init -> DutyCycle = I2C_DUTYCYCLE_16_9 ;
320375 init -> GeneralCallMode = args [3 ].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED ;
321376 init -> NoStretchMode = I2C_NOSTRETCH_DISABLED ;
322- init -> OwnAddress2 = 0xfe ; // unused
377+ init -> OwnAddress2 = 0 ; // unused
378+ init -> NoStretchMode = I2C_NOSTRETCH_DISABLE ;
323379
324380 // init the I2C bus
325381 i2c_init (self -> i2c );
@@ -753,5 +809,3 @@ const mp_obj_type_t pyb_i2c_type = {
753809 .make_new = pyb_i2c_make_new ,
754810 .locals_dict = (mp_obj_t )& pyb_i2c_locals_dict ,
755811};
756-
757- #endif // STM32F7
0 commit comments