diff options
Diffstat (limited to 'stmhal/i2c.c')
-rw-r--r-- | stmhal/i2c.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/stmhal/i2c.c b/stmhal/i2c.c index 29c350d22f..4a792d1630 100644 --- a/stmhal/i2c.c +++ b/stmhal/i2c.c @@ -37,14 +37,6 @@ #include "dma.h" #include "i2c.h" -#if !defined(MICROPY_HW_I2C_BAUDRATE_DEFAULT) -#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 400000 -#endif - -#if !defined(MICROPY_HW_I2C_BAUDRATE_MAX) -#define MICROPY_HW_I2C_BAUDRATE_MAX 400000 -#endif - /// \moduleref pyb /// \class I2C - a two-wire serial protocol /// @@ -134,10 +126,42 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = { #endif }; -#if defined(MICROPY_HW_I2C_BAUDRATE_TIMING) +#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4) + // The STM32F0, F3, F7 and L4 use a TIMINGR register rather than ClockSpeed and // DutyCycle. +#if defined(STM32F746xx) + +// The value 0x40912732 was obtained from the DISCOVERY_I2Cx_TIMING constant +// defined in the STM32F7Cube file Drivers/BSP/STM32F746G-Discovery/stm32f7456g_discovery.h +#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x40912732}} +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (100000) +#define MICROPY_HW_I2C_BAUDRATE_MAX (100000) + +#elif defined(STM32F767xx) || defined(STM32F769xx) + +// These timing values are for f_I2CCLK=54MHz and are only approximate +#define MICROPY_HW_I2C_BAUDRATE_TIMING { \ + {100000, 0xb0420f13}, \ + {400000, 0x70330309}, \ + {1000000, 0x50100103}, \ + } +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (400000) +#define MICROPY_HW_I2C_BAUDRATE_MAX (1000000) + +#elif defined(MCU_SERIES_L4) + +// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant +// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h +#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x90112626}} +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (100000) +#define MICROPY_HW_I2C_BAUDRATE_MAX (100000) + +#else +#error "no I2C timings for this MCU" +#endif + STATIC const struct { uint32_t baudrate; uint32_t timing; @@ -167,6 +191,9 @@ uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) { #else +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (400000) +#define MICROPY_HW_I2C_BAUDRATE_MAX (400000) + STATIC void i2c_set_baudrate(I2C_InitTypeDef *init, uint32_t baudrate) { init->ClockSpeed = baudrate; init->DutyCycle = I2C_DUTYCYCLE_16_9; @@ -176,7 +203,7 @@ uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) { return init->ClockSpeed; } -#endif // MICROPY_HW_I2C_BAUDRATE_TIMING +#endif void i2c_init0(void) { // reset the I2C1 handles @@ -346,7 +373,7 @@ STATIC void i2c_reset_after_error(I2C_HandleTypeDef *i2c) { // stop bit was generated and bus is back to normal return; } - HAL_Delay(1); + mp_hal_delay_ms(1); } // bus was/is busy, need to reset the peripheral to get it to work again i2c_deinit(i2c); @@ -733,12 +760,14 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ if (!use_dma) { status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, args[2].u_int); } else { + MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len); status = HAL_I2C_Master_Transmit_DMA(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len); } } else { if (!use_dma) { status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, args[2].u_int); } else { + MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len); status = HAL_I2C_Slave_Transmit_DMA(self->i2c, bufinfo.buf, bufinfo.len); } } @@ -807,12 +836,14 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ if (!use_dma) { status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len, args[2].u_int); } else { + MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len); status = HAL_I2C_Master_Receive_DMA(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len); } } else { if (!use_dma) { status = HAL_I2C_Slave_Receive(self->i2c, (uint8_t*)vstr.buf, vstr.len, args[2].u_int); } else { + MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len); status = HAL_I2C_Slave_Receive_DMA(self->i2c, (uint8_t*)vstr.buf, vstr.len); } } @@ -893,6 +924,7 @@ STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_ dma_init(&rx_dma, self->rx_dma_descr, self->i2c); self->i2c->hdmatx = NULL; self->i2c->hdmarx = &rx_dma; + MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len); status = HAL_I2C_Mem_Read_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len); if (status == HAL_OK) { status = i2c_wait_dma_finished(self->i2c, args[3].u_int); @@ -961,6 +993,7 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp dma_init(&tx_dma, self->tx_dma_descr, self->i2c); self->i2c->hdmatx = &tx_dma; self->i2c->hdmarx = NULL; + MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len); status = HAL_I2C_Mem_Write_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len); if (status == HAL_OK) { status = i2c_wait_dma_finished(self->i2c, args[3].u_int); @@ -977,22 +1010,22 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_write_obj, 1, pyb_i2c_mem_write); -STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = { +STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = { // instance methods - { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_i2c_init_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_i2c_deinit_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_i2c_send_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_i2c_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_i2c_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_ready), MP_ROM_PTR(&pyb_i2c_is_ready_obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&pyb_i2c_scan_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_i2c_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_i2c_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem_read), MP_ROM_PTR(&pyb_i2c_mem_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem_write), MP_ROM_PTR(&pyb_i2c_mem_write_obj) }, // class constants /// \constant MASTER - for initialising the bus to master mode /// \constant SLAVE - for initialising the bus to slave mode - { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(PYB_I2C_MASTER) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE), MP_OBJ_NEW_SMALL_INT(PYB_I2C_SLAVE) }, + { MP_ROM_QSTR(MP_QSTR_MASTER), MP_ROM_INT(PYB_I2C_MASTER) }, + { MP_ROM_QSTR(MP_QSTR_SLAVE), MP_ROM_INT(PYB_I2C_SLAVE) }, }; STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table); @@ -1002,5 +1035,5 @@ const mp_obj_type_t pyb_i2c_type = { .name = MP_QSTR_I2C, .print = pyb_i2c_print, .make_new = pyb_i2c_make_new, - .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict, + .locals_dict = (mp_obj_dict_t*)&pyb_i2c_locals_dict, }; |