diff --git a/esp8266/modpybspi.c b/esp8266/modpybspi.c index acc3c25125..e974547111 100644 --- a/esp8266/modpybspi.c +++ b/esp8266/modpybspi.c @@ -36,10 +36,24 @@ /******************************************************************************/ // MicroPython bindings for SPI +STATIC uint32_t baudrate_from_delay_half(uint32_t delay_half) { + return 500000 / delay_half; +} + +STATIC uint32_t baudrate_to_delay_half(uint32_t baudrate) { + uint32_t delay_half = 500000 / baudrate; + // round delay_half up so that: actual_baudrate <= requested_baudrate + if (500000 % baudrate != 0) { + delay_half += 1; + } + return delay_half; +} + STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "SPI(baudrate=%u, polarity=%u, phase=%u, sck=%u, mosi=%u, miso=%u)", - self->baudrate, self->polarity, self->phase, self->sck, self->mosi, self->miso); + baudrate_from_delay_half(self->delay_half), + self->polarity, self->phase, self->sck, self->mosi, self->miso); } STATIC void pyb_spi_init_helper(mp_machine_soft_spi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -56,7 +70,7 @@ STATIC void pyb_spi_init_helper(mp_machine_soft_spi_obj_t *self, size_t n_args, mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); if (args[ARG_baudrate].u_int != -1) { - self->baudrate = args[ARG_baudrate].u_int; + self->delay_half = baudrate_to_delay_half(args[ARG_baudrate].u_int); } if (args[ARG_polarity].u_int != -1) { self->polarity = args[ARG_polarity].u_int; @@ -86,7 +100,7 @@ mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t); self->base.type = &pyb_spi_type; // set defaults - self->baudrate = 500000; + self->delay_half = baudrate_to_delay_half(500000); self->polarity = 0; self->phase = 0; self->sck = 14; diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 3a34b7fb08..b0bd76faf9 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -34,8 +34,10 @@ void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { mp_machine_soft_spi_obj_t *self = (mp_machine_soft_spi_obj_t*)self_in; + uint32_t delay_half = self->delay_half; + // only MSB transfer is implemented - uint32_t delay_half = 500000 / self->baudrate + 1; + for (size_t i = 0; i < len; ++i) { uint8_t data_out = src[i]; uint8_t data_in = 0; diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h index e1922c6e8b..316d06646e 100644 --- a/extmod/machine_spi.h +++ b/extmod/machine_spi.h @@ -37,7 +37,7 @@ typedef struct _mp_machine_spi_p_t { typedef struct _mp_machine_soft_spi_obj_t { mp_obj_base_t base; - uint32_t baudrate; + uint32_t delay_half; // microsecond delay for half SCK period uint8_t polarity; uint8_t phase; mp_hal_pin_obj_t sck; diff --git a/stmhal/spi.c b/stmhal/spi.c index 46da05facf..8ec6f86275 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -944,10 +944,23 @@ STATIC MP_DEFINE_CONST_DICT(machine_spi_locals_dict, machine_spi_locals_dict_tab /* code for soft implementation ***********************************************/ +STATIC uint32_t baudrate_from_delay_half(uint32_t delay_half) { + return 500000 / delay_half; +} + +STATIC uint32_t baudrate_to_delay_half(uint32_t baudrate) { + uint32_t delay_half = 500000 / baudrate; + // round delay_half up so that: actual_baudrate <= requested_baudrate + if (500000 % baudrate != 0) { + delay_half += 1; + } + return delay_half; +} + STATIC void machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "SPI(-1, baudrate=%u, polarity=%u, phase=%u, sck=%q, mosi=%q, miso=%q)", - self->baudrate, self->polarity, self->phase, + baudrate_from_delay_half(self->delay_half), self->polarity, self->phase, self->sck->name, self->mosi->name, self->miso->name); } @@ -957,7 +970,7 @@ STATIC mp_obj_t machine_soft_spi_make_new(mp_arg_val_t *args) { self->base.type = &machine_soft_spi_type; // set parameters - self->baudrate = args[ARG_NEW_baudrate].u_int; + self->delay_half = baudrate_to_delay_half(args[ARG_NEW_baudrate].u_int); self->polarity = args[ARG_NEW_polarity].u_int; self->phase = args[ARG_NEW_phase].u_int; if (args[ARG_NEW_bits].u_int != 8) { @@ -989,7 +1002,7 @@ STATIC void machine_soft_spi_init(mp_obj_t self_in, mp_arg_val_t *args) { // update parameters if (args[ARG_INIT_baudrate].u_int != -1) { - self->baudrate = args[ARG_INIT_baudrate].u_int; + self->delay_half = baudrate_to_delay_half(args[ARG_INIT_baudrate].u_int); } if (args[ARG_INIT_polarity].u_int != -1) { self->polarity = args[ARG_INIT_polarity].u_int;