diff --git a/esp8266/modpybhspi.c b/esp8266/modpybhspi.c index f80fbae00a..c4d4dcee8d 100644 --- a/esp8266/modpybhspi.c +++ b/esp8266/modpybhspi.c @@ -35,6 +35,7 @@ #include "py/runtime.h" #include "py/stream.h" #include "py/mphal.h" +#include "extmod/machine_spi.h" #include "hspi.h" @@ -47,6 +48,58 @@ typedef struct _pyb_hspi_obj_t { } pyb_hspi_obj_t; +STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t *src_buf, size_t dest_len, uint8_t *dest_buf) { + (void)self_in; + + if (dest_len == 0) { + // fast case when we only need to write data + size_t chunk_size = 1024; + size_t count = src_len / chunk_size; + size_t i = 0; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + spi_tx8fast(HSPI, src_buf[i]); + ++i; + } + ets_loop_iter(); + } + while (i < src_len) { + spi_tx8fast(HSPI, src_buf[i]); + ++i; + } + } else { + // we need to read and write data + + // Process data in chunks, let the pending tasks run in between + size_t chunk_size = 1024; // TODO this should depend on baudrate + size_t count = dest_len / chunk_size; + size_t i = 0; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + uint32_t data_out; + if (src_len == 1) { + data_out = src_buf[0]; + } else { + data_out = src_buf[i]; + } + dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0); + ++i; + } + ets_loop_iter(); + } + while (i < dest_len) { + uint32_t data_out; + if (src_len == 1) { + data_out = src_buf[0]; + } else { + data_out = src_buf[i]; + } + dest_buf[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out, 8, 0); + ++i; + } + } +} + /******************************************************************************/ // MicroPython bindings for HSPI @@ -126,133 +179,25 @@ STATIC mp_obj_t pyb_hspi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_ } MP_DEFINE_CONST_FUN_OBJ_KW(pyb_hspi_init_obj, 1, pyb_hspi_init); - -STATIC mp_obj_t pyb_hspi_read(size_t n_args, const mp_obj_t *args) { - vstr_t dest_buf; - vstr_init_len(&dest_buf, mp_obj_get_int(args[1])); - uint8_t write_byte = 0; - if (n_args == 3) { - write_byte = mp_obj_get_int(args[2]); - } - // Process data in chunks, let the pending tasks run in between - size_t chunk_size = 1024; // TODO this should depend on baudrate - size_t count = dest_buf.len / chunk_size; - size_t i = 0; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)write_byte, 8, 0); - ++i; - } - ets_loop_iter(); - } - while (i < dest_buf.len) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)write_byte, 8, 0); - ++i; - } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &dest_buf); -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_hspi_read_obj, 2, 3, pyb_hspi_read); - - -STATIC mp_obj_t pyb_hspi_readinto(size_t n_args, const mp_obj_t *args) { - mp_buffer_info_t dest_buf; - mp_get_buffer_raise(args[1], &dest_buf, MP_BUFFER_WRITE); - uint8_t write_byte = 0; - if (n_args == 3) { - write_byte = mp_obj_get_int(args[2]); - } - - size_t chunk_size = 1024; - size_t count = dest_buf.len / chunk_size; - size_t i = 0; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)write_byte, 8, 0); - ++i; - } - ets_loop_iter(); - } - while (i < dest_buf.len) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)write_byte, 8, 0); - ++i; - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_hspi_readinto_obj, 2, 3, pyb_hspi_readinto); - - -STATIC mp_obj_t pyb_hspi_write(mp_obj_t self_in, mp_obj_t wr_buf_in) { - mp_buffer_info_t src_buf; - mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ); - - size_t chunk_size = 1024; - size_t count = src_buf.len / chunk_size; - size_t i = 0; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - spi_tx8fast(HSPI, ((const uint8_t*)src_buf.buf)[i]); - ++i; - } - ets_loop_iter(); - } - while (i < src_buf.len) { - spi_tx8fast(HSPI, ((const uint8_t*)src_buf.buf)[i]); - ++i; - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(pyb_hspi_write_obj, pyb_hspi_write); - - -STATIC mp_obj_t pyb_hspi_write_readinto(mp_obj_t self_in, mp_obj_t wr_buf_in, mp_obj_t rd_buf_in) { - mp_buffer_info_t src_buf; - mp_get_buffer_raise(wr_buf_in, &src_buf, MP_BUFFER_READ); - mp_buffer_info_t dest_buf; - mp_get_buffer_raise(rd_buf_in, &dest_buf, MP_BUFFER_WRITE); - if (src_buf.len != dest_buf.len) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "buffers must be the same length")); - } - - size_t chunk_size = 1024; - size_t count = src_buf.len / chunk_size; - size_t i = 0; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)(((const uint8_t*)src_buf.buf)[i]), 8, 0); - ++i; - } - ets_loop_iter(); - } - while (i < src_buf.len) { - ((uint8_t*)dest_buf.buf)[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, - (uint32_t)(((const uint8_t*)src_buf.buf)[i]), 8, 0); - ++i; - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_3(pyb_hspi_write_readinto_obj, pyb_hspi_write_readinto); - - STATIC const mp_rom_map_elem_t pyb_hspi_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_hspi_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_hspi_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&pyb_hspi_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_hspi_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&pyb_hspi_write_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) }, }; STATIC MP_DEFINE_CONST_DICT(pyb_hspi_locals_dict, pyb_hspi_locals_dict_table); +STATIC const mp_machine_spi_p_t pyb_hspi_p = { + .transfer = hspi_transfer, +}; + const mp_obj_type_t pyb_hspi_type = { { &mp_type_type }, .name = MP_QSTR_HSPI, .print = pyb_hspi_print, .make_new = pyb_hspi_make_new, + .protocol = &pyb_hspi_p, .locals_dict = (mp_obj_dict_t*)&pyb_hspi_locals_dict, };