diff options
author | Damien George <damien.p.george@gmail.com> | 2016-10-03 16:43:44 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2016-10-03 16:43:44 +1100 |
commit | d434ce3fca088959c4a4bf525b9d730ec9bdb7b4 (patch) | |
tree | 12e8b38116036759da7ce741c5be904bec58778d | |
parent | a22a67661aa4f6309efa1e81b279629050fd1966 (diff) | |
download | micropython-d434ce3fca088959c4a4bf525b9d730ec9bdb7b4.tar.gz micropython-d434ce3fca088959c4a4bf525b9d730ec9bdb7b4.zip |
extmod/machine_spi: Factor out software SPI code from esp8266 to extmod.
-rw-r--r-- | esp8266/modpybspi.c | 55 | ||||
-rw-r--r-- | extmod/machine_spi.c | 37 | ||||
-rw-r--r-- | extmod/machine_spi.h | 13 |
3 files changed, 54 insertions, 51 deletions
diff --git a/esp8266/modpybspi.c b/esp8266/modpybspi.c index b9650954f3..acc3c25125 100644 --- a/esp8266/modpybspi.c +++ b/esp8266/modpybspi.c @@ -28,68 +28,21 @@ #include <stdint.h> #include <string.h> -#include "ets_sys.h" -#include "etshal.h" -#include "ets_alt_task.h" - #include "py/runtime.h" #include "py/stream.h" #include "py/mphal.h" #include "extmod/machine_spi.h" -typedef struct _pyb_spi_obj_t { - mp_obj_base_t base; - uint32_t baudrate; - uint8_t polarity; - uint8_t phase; - mp_hal_pin_obj_t sck; - mp_hal_pin_obj_t mosi; - mp_hal_pin_obj_t miso; -} pyb_spi_obj_t; - -STATIC void mp_hal_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { - pyb_spi_obj_t *self = (pyb_spi_obj_t*)self_in; - // 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; - for (int j = 0; j < 8; ++j, data_out <<= 1) { - mp_hal_pin_write(self->mosi, (data_out >> 7) & 1); - if (self->phase == 0) { - ets_delay_us(delay_half); - mp_hal_pin_write(self->sck, 1 - self->polarity); - } else { - mp_hal_pin_write(self->sck, 1 - self->polarity); - ets_delay_us(delay_half); - } - data_in = (data_in << 1) | mp_hal_pin_read(self->miso); - if (self->phase == 0) { - ets_delay_us(delay_half); - mp_hal_pin_write(self->sck, self->polarity); - } else { - mp_hal_pin_write(self->sck, self->polarity); - ets_delay_us(delay_half); - } - } - if (dest != NULL) { - dest[i] = data_in; - } - // make sure pending tasks have a chance to run - ets_loop_iter(); - } -} - /******************************************************************************/ // MicroPython bindings for SPI STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - pyb_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + 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); } -STATIC void pyb_spi_init_helper(pyb_spi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +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) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, @@ -130,7 +83,7 @@ STATIC void pyb_spi_init_helper(pyb_spi_obj_t *self, size_t n_args, const mp_obj mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - pyb_spi_obj_t *self = m_new_obj(pyb_spi_obj_t); + 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; @@ -162,7 +115,7 @@ STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table); STATIC const mp_machine_spi_p_t pyb_spi_p = { - .transfer = mp_hal_spi_transfer, + .transfer = mp_machine_soft_spi_transfer, }; const mp_obj_type_t pyb_spi_type = { diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 1c64cf511b..3a34b7fb08 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -32,6 +32,43 @@ #if MICROPY_PY_MACHINE_SPI +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; + // 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; + for (int j = 0; j < 8; ++j, data_out <<= 1) { + mp_hal_pin_write(self->mosi, (data_out >> 7) & 1); + if (self->phase == 0) { + mp_hal_delay_us_fast(delay_half); + mp_hal_pin_write(self->sck, 1 - self->polarity); + } else { + mp_hal_pin_write(self->sck, 1 - self->polarity); + mp_hal_delay_us_fast(delay_half); + } + data_in = (data_in << 1) | mp_hal_pin_read(self->miso); + if (self->phase == 0) { + mp_hal_delay_us_fast(delay_half); + mp_hal_pin_write(self->sck, self->polarity); + } else { + mp_hal_pin_write(self->sck, self->polarity); + mp_hal_delay_us_fast(delay_half); + } + } + if (dest != NULL) { + dest[i] = data_in; + } + + // Some ports need a regular callback, but probably we don't need + // to do this every byte, or even at all. + #ifdef MICROPY_EVENT_POLL_HOOK + MICROPY_EVENT_POLL_HOOK; + #endif + } +} + STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) { mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self); mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol; diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h index 35a911d919..e1922c6e8b 100644 --- a/extmod/machine_spi.h +++ b/extmod/machine_spi.h @@ -28,12 +28,25 @@ #define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H #include "py/obj.h" +#include "py/mphal.h" // SPI protocol typedef struct _mp_machine_spi_p_t { void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest); } mp_machine_spi_p_t; +typedef struct _mp_machine_soft_spi_obj_t { + mp_obj_base_t base; + uint32_t baudrate; + uint8_t polarity; + uint8_t phase; + mp_hal_pin_obj_t sck; + mp_hal_pin_obj_t mosi; + mp_hal_pin_obj_t miso; +} mp_machine_soft_spi_obj_t; + +void mp_machine_soft_spi_transfer(mp_obj_base_t *self, size_t len, const uint8_t *src, uint8_t *dest); + MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_read_obj); MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_readinto_obj); MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_obj); |