From 0ec1d9e2de270dd9433a3fc62f1e6d8e3f235f98 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 27 Mar 2017 10:09:10 -0700 Subject: [PATCH 01/17] esp32/README.md Added troubleshooting section to the end --- esp32/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/esp32/README.md b/esp32/README.md index 32c848e44..30adb92ac 100644 --- a/esp32/README.md +++ b/esp32/README.md @@ -159,3 +159,10 @@ boot.py file): import machine antenna = machine.Pin(16, machine.Pin.OUT, value=0) ``` + + +Troubleshooting +--------------- + +* Continuous reboots after programming: Ensure FLASH_MODE is correct for your board (e.g. ESP-WROOM-32 should be DIO). Perform a `make clean`, rebuild, redeploy. + From f41a01a30a4350c3ab325cecc016a0fa4959ab1b Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Thu, 30 Mar 2017 14:54:31 -0700 Subject: [PATCH 02/17] esp32/mpconfigport.h: Added support for HSPI --- esp32/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/esp32/mpconfigport.h b/esp32/mpconfigport.h index 16676c6ac..215301fa0 100644 --- a/esp32/mpconfigport.h +++ b/esp32/mpconfigport.h @@ -122,6 +122,7 @@ #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SPI (1) +#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hspi_make_new #define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0) #define MICROPY_PY_MACHINE_SPI_MAX_BAUDRATE (ets_get_cpu_frequency() * 1000000 / 200) // roughly #define MICROPY_PY_USSL (1) From 192a0326ead449de59788c5a7114f927a667ecdc Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Thu, 30 Mar 2017 14:55:12 -0700 Subject: [PATCH 03/17] esp32/machine_hspi.c: Adding HW SPI support esp32/machine_hspi.h: Adding HW SPI support --- esp32/machine_hspi.c | 186 +++++++++++++++++++++++++++++++++++++++++++ esp32/machine_hspi.h | 49 ++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 esp32/machine_hspi.c create mode 100644 esp32/machine_hspi.h diff --git a/esp32/machine_hspi.c b/esp32/machine_hspi.c new file mode 100644 index 000000000..bd3f2cc7e --- /dev/null +++ b/esp32/machine_hspi.c @@ -0,0 +1,186 @@ +/* +* This file is part of the MicroPython project, http://micropython.org/ +* +* The MIT License (MIT) +* +* Copyright (c) 2016 Damien P. George +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include +#include +#include + + +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mphal.h" +#include "extmod/machine_spi.h" +#include "machine_hspi.h" +#include "modmachine.h" +#include "hspi.h" + +// if a port didn't define MSB/LSB constants then provide them +#ifndef MICROPY_PY_MACHINE_SPI_MSB +#define MICROPY_PY_MACHINE_SPI_MSB (0) +#define MICROPY_PY_MACHINE_SPI_LSB (1) +#endif + + + +STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { + machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); + int bits_to_send = len * self->bits; + if (self->deinitialized) { + return; + } + + struct spi_transaction_t transaction = { + .flags = 0, + .length = bits_to_send, + .tx_buffer = src, + .rx_buffer = dest, + }; + bool shortMsg = len <= 4; + + if(shortMsg) { + if (src != NULL) { + memcpy(&transaction.tx_data, src, len); + transaction.flags |= SPI_TRANS_USE_TXDATA; + } + if (dest != NULL) { + transaction.flags |= SPI_TRANS_USE_RXDATA; + } + } + + spi_device_transmit(self->spi, &transaction); + + if (shortMsg && dest != NULL) { + memcpy(dest, &transaction.rx_data, len); + } +} + +/******************************************************************************/ +// MicroPython bindings for HSPI + +STATIC void machine_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "HSPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", + self->host, self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->sck, self->mosi, self->miso ); +} + +STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in; + esp_err_t ret; + + enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 1} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} }, + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), + allowed_args, args); + + self->host = args[ARG_id].u_int; + self->baudrate = args[ARG_baudrate].u_int; + self->polarity = args[ARG_polarity].u_int ? 1 : 0; + self->phase = args[ARG_phase].u_int ? 1 : 0; + self->bits = args[ARG_bits].u_int; + self->firstbit = args[ARG_firstbit].u_int; + self->sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj); + self->miso = args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj); + self->mosi = args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj); + self->deinitialized = false; + + spi_bus_config_t buscfg = { + .miso_io_num = self->miso, + .mosi_io_num = self->mosi, + .sclk_io_num = self->sck, + .quadwp_io_num = -1, + .quadhd_io_num = -1 + }; + spi_device_interface_config_t devcfg = { + .clock_speed_hz = self->baudrate, + .mode = self->phase | (self->polarity << 1), + .spics_io_num = -1, // No CS pin + .queue_size = 1, + .pre_cb = NULL + }; + + //Initialize the SPI bus + // FIXME: Does the DMA matter? There are two + ret=spi_bus_initialize(self->host, &buscfg, 1); + assert(ret == ESP_OK); + ret=spi_bus_add_device(self->host, &devcfg, &self->spi); + assert(ret == ESP_OK); +} + +STATIC void machine_hspi_deinit(mp_obj_base_t *self_in) { + machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in; + esp_err_t ret; + if (!self->deinitialized) { + self->deinitialized = true; + ret = spi_bus_remove_device(self->spi); + assert(ret == ESP_OK); + ret = spi_bus_free(self->host); + assert(ret == ESP_OK); + } +} + +mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // args[0] holds the id of the peripheral + int host = mp_obj_get_int(args[0]); + if (host != HSPI_HOST && host != VSPI_HOST) { + mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)"); + } + + machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t); + self->base.type = &machine_hspi_type; + // set defaults + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_hspi_init((mp_obj_base_t*)self, n_args, args, &kw_args); + return MP_OBJ_FROM_PTR(self); +} + +STATIC const mp_machine_spi_p_t machine_hspi_p = { + .init = machine_hspi_init, + .deinit = machine_hspi_deinit, + .transfer = machine_hspi_transfer, +}; + +const mp_obj_type_t machine_hspi_type = { + { &mp_type_type }, + .name = MP_QSTR_HSPI, + .print = machine_hspi_print, + .make_new = machine_hspi_make_new, + .protocol = &machine_hspi_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, +}; diff --git a/esp32/machine_hspi.h b/esp32/machine_hspi.h new file mode 100644 index 000000000..04557f0d3 --- /dev/null +++ b/esp32/machine_hspi.h @@ -0,0 +1,49 @@ +/* +* This file is part of the MicroPython project, http://micropython.org/ +* +* The MIT License (MIT) +* +* Copyright (c) 2016 Damien P. George +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#ifndef MICROPY_INCLUDED_MACHINE_HSPI_H +#define MICROPY_INCLUDED_MACHINE_HSPI_H + +#include "driver/spi_master.h" + +typedef struct _machine_hspi_obj_t { + mp_obj_base_t base; + spi_host_device_t host; + uint32_t baudrate; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + uint8_t firstbit; + int8_t sck; + int8_t mosi; + int8_t miso; + spi_device_handle_t spi; + bool deinitialized; +} machine_hspi_obj_t; + +extern const mp_obj_type_t machine_hspi_type ; + +#endif // MICROPY_INCLUDED_MACHINE_HSPI_H From e0609a42e2e19d6bac8464e0e145ec6c48c5c721 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 07:45:47 -0700 Subject: [PATCH 04/17] esp32/machine_hspi.*: Renamed to machine_hw_spi.* --- esp32/{machine_hspi.c => machine_hw_spi.c} | 27 +++++++++++++--------- esp32/{machine_hspi.h => machine_hw_spi.h} | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) rename esp32/{machine_hspi.c => machine_hw_spi.c} (93%) rename esp32/{machine_hspi.h => machine_hw_spi.h} (98%) diff --git a/esp32/machine_hspi.c b/esp32/machine_hw_spi.c similarity index 93% rename from esp32/machine_hspi.c rename to esp32/machine_hw_spi.c index bd3f2cc7e..617167a1b 100644 --- a/esp32/machine_hspi.c +++ b/esp32/machine_hw_spi.c @@ -35,7 +35,7 @@ #include "extmod/machine_spi.h" #include "machine_hspi.h" #include "modmachine.h" -#include "hspi.h" + // if a port didn't define MSB/LSB constants then provide them #ifndef MICROPY_PY_MACHINE_SPI_MSB @@ -55,11 +55,12 @@ STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint struct spi_transaction_t transaction = { .flags = 0, .length = bits_to_send, - .tx_buffer = src, - .rx_buffer = dest, + .tx_buffer = NULL, + .rx_buffer = NULL, }; bool shortMsg = len <= 4; + if(shortMsg) { if (src != NULL) { memcpy(&transaction.tx_data, src, len); @@ -68,6 +69,9 @@ STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint if (dest != NULL) { transaction.flags |= SPI_TRANS_USE_RXDATA; } + } else { + transaction.tx_buffer = src; + transaction.rx_buffer = dest; } spi_device_transmit(self->spi, &transaction); @@ -108,7 +112,12 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - self->host = args[ARG_id].u_int; + int host = args[ARG_id].u_int; + if (host != HSPI_HOST && host != VSPI_HOST) { + mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)"); + } + + self->host = host; self->baudrate = args[ARG_baudrate].u_int; self->polarity = args[ARG_polarity].u_int ? 1 : 0; self->phase = args[ARG_phase].u_int ? 1 : 0; @@ -131,14 +140,15 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob .mode = self->phase | (self->polarity << 1), .spics_io_num = -1, // No CS pin .queue_size = 1, + .flags = self->firstbit == MICROPY_PY_MACHINE_SPI_LSB ? SPI_DEVICE_TXBIT_LSBFIRST | SPI_DEVICE_RXBIT_LSBFIRST : 0, .pre_cb = NULL }; //Initialize the SPI bus // FIXME: Does the DMA matter? There are two - ret=spi_bus_initialize(self->host, &buscfg, 1); + ret = spi_bus_initialize(self->host, &buscfg, 1); assert(ret == ESP_OK); - ret=spi_bus_add_device(self->host, &devcfg, &self->spi); + ret = spi_bus_add_device(self->host, &devcfg, &self->spi); assert(ret == ESP_OK); } @@ -156,11 +166,6 @@ STATIC void machine_hspi_deinit(mp_obj_base_t *self_in) { mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // args[0] holds the id of the peripheral - int host = mp_obj_get_int(args[0]); - if (host != HSPI_HOST && host != VSPI_HOST) { - mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)"); - } - machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t); self->base.type = &machine_hspi_type; // set defaults diff --git a/esp32/machine_hspi.h b/esp32/machine_hw_spi.h similarity index 98% rename from esp32/machine_hspi.h rename to esp32/machine_hw_spi.h index 04557f0d3..b64143b4f 100644 --- a/esp32/machine_hspi.h +++ b/esp32/machine_hw_spi.h @@ -31,7 +31,7 @@ typedef struct _machine_hspi_obj_t { mp_obj_base_t base; - spi_host_device_t host; + spi_host_device_t host; uint32_t baudrate; uint8_t polarity; uint8_t phase; From c046e4fd189b38c5f0a5c26bdbf1b4b273acbeda Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 10:55:51 -0700 Subject: [PATCH 05/17] esp32/machine_hw_spi.*: Renamed internals from hspi --> hw_spi --- esp32/Makefile | 4 +++- esp32/machine_hw_spi.c | 50 +++++++++++++++++++++--------------------- esp32/machine_hw_spi.h | 12 +++++----- esp32/mpconfigport.h | 2 +- esp32/scratch.txt | 39 ++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 esp32/scratch.txt diff --git a/esp32/Makefile b/esp32/Makefile index 66bb4bc49..87063eb2d 100644 --- a/esp32/Makefile +++ b/esp32/Makefile @@ -16,7 +16,7 @@ include ../py/py.mk PORT ?= /dev/ttyUSB0 BAUD ?= 460800 -FLASH_MODE ?= qio +FLASH_MODE ?= dio FLASH_FREQ ?= 40m FLASH_SIZE ?= 4MB CROSS_COMPILE ?= xtensa-esp32-elf- @@ -122,6 +122,7 @@ SRC_C = \ machine_pin.c \ machine_touchpad.c \ machine_adc.c \ + machine_hw_spi.c \ machine_dac.c \ modmachine.c \ modnetwork.c \ @@ -199,6 +200,7 @@ ESPIDF_DRIVER_O = $(addprefix $(ESPCOMP)/driver/,\ uart.o \ periph_ctrl.o \ ledc.o \ + spi_master.o \ gpio.o \ timer.o \ rtc_module.o \ diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 617167a1b..5306c820b 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -33,7 +33,7 @@ #include "py/stream.h" #include "py/mphal.h" #include "extmod/machine_spi.h" -#include "machine_hspi.h" +#include "machine_hw_spi.h" #include "modmachine.h" @@ -45,8 +45,8 @@ -STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { - machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); int bits_to_send = len * self->bits; if (self->deinitialized) { return; @@ -82,18 +82,18 @@ STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint } /******************************************************************************/ -// MicroPython bindings for HSPI +// MicroPython bindings for hw_spi -STATIC void machine_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "HSPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", +STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "hw_spi(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", self->host, self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, self->sck, self->mosi, self->miso ); } -STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in; +STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; esp_err_t ret; enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; @@ -114,7 +114,7 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob int host = args[ARG_id].u_int; if (host != HSPI_HOST && host != VSPI_HOST) { - mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)"); + mp_raise_ValueError("SPI ID must be either hw_spi(1) or VSPI(2)"); } self->host = host; @@ -152,8 +152,8 @@ STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ob assert(ret == ESP_OK); } -STATIC void machine_hspi_deinit(mp_obj_base_t *self_in) { - machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in; +STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; esp_err_t ret; if (!self->deinitialized) { self->deinitialized = true; @@ -164,28 +164,28 @@ STATIC void machine_hspi_deinit(mp_obj_base_t *self_in) { } } -mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // args[0] holds the id of the peripheral - machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t); - self->base.type = &machine_hspi_type; + machine_hw_spi_obj_t *self = m_new_obj(machine_hw_spi_obj_t); + self->base.type = &machine_hw_spi_type; // set defaults mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_hspi_init((mp_obj_base_t*)self, n_args, args, &kw_args); + machine_hw_spi_init((mp_obj_base_t*)self, n_args, args, &kw_args); return MP_OBJ_FROM_PTR(self); } -STATIC const mp_machine_spi_p_t machine_hspi_p = { - .init = machine_hspi_init, - .deinit = machine_hspi_deinit, - .transfer = machine_hspi_transfer, +STATIC const mp_machine_spi_p_t machine_hw_spi_p = { + .init = machine_hw_spi_init, + .deinit = machine_hw_spi_deinit, + .transfer = machine_hw_spi_transfer, }; -const mp_obj_type_t machine_hspi_type = { +const mp_obj_type_t machine_hw_spi_type = { { &mp_type_type }, - .name = MP_QSTR_HSPI, - .print = machine_hspi_print, - .make_new = machine_hspi_make_new, - .protocol = &machine_hspi_p, + .name = MP_QSTR_hw_spi, + .print = machine_hw_spi_print, + .make_new = machine_hw_spi_make_new, + .protocol = &machine_hw_spi_p, .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, }; diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h index b64143b4f..e6be895ec 100644 --- a/esp32/machine_hw_spi.h +++ b/esp32/machine_hw_spi.h @@ -24,12 +24,12 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MACHINE_HSPI_H -#define MICROPY_INCLUDED_MACHINE_HSPI_H +#ifndef MICROPY_INCLUDED_MACHINE_HW_SPI_H +#define MICROPY_INCLUDED_MACHINE_HW_SPI_H #include "driver/spi_master.h" -typedef struct _machine_hspi_obj_t { +typedef struct _machine_hw_spi_obj_t { mp_obj_base_t base; spi_host_device_t host; uint32_t baudrate; @@ -42,8 +42,8 @@ typedef struct _machine_hspi_obj_t { int8_t miso; spi_device_handle_t spi; bool deinitialized; -} machine_hspi_obj_t; +} machine_hw_spi_obj_t; -extern const mp_obj_type_t machine_hspi_type ; +extern const mp_obj_type_t machine_hw_spi_type ; -#endif // MICROPY_INCLUDED_MACHINE_HSPI_H +#endif // MICROPY_INCLUDED_MACHINE_HW_SPI_H diff --git a/esp32/mpconfigport.h b/esp32/mpconfigport.h index 215301fa0..151361716 100644 --- a/esp32/mpconfigport.h +++ b/esp32/mpconfigport.h @@ -122,7 +122,7 @@ #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SPI (1) -#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hspi_make_new +#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hw_spi_make_new #define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0) #define MICROPY_PY_MACHINE_SPI_MAX_BAUDRATE (ets_get_cpu_frequency() * 1000000 / 200) // roughly #define MICROPY_PY_USSL (1) diff --git a/esp32/scratch.txt b/esp32/scratch.txt new file mode 100644 index 000000000..e57e392bf --- /dev/null +++ b/esp32/scratch.txt @@ -0,0 +1,39 @@ +import machine as m +p = m.Pin(4) +r = m.RTC() +p.init(p.IN, p.PULL_UP) +r.wake_on_ext0(pin = p, level = 0) +m.deepsleep() + +import machine as m +pins = (m.Pin(2), m.Pin(4)) +for p in pins: p.init(m.Pin.IN, m.Pin.PULL_UP) + +r = m.RTC() +r.wake_on_ext1(pins = pins, level = r.WAKEUP_ALL_LOW) +m.deepsleep() + + +import machine as m +r = m.RTC() +r.irq(trigger=r.ALARM0, wake=m.DEEPSLEEP) +r.alarm(r.ALARM0, 3000) +m.deepsleep() + +import machine as m +s = m.SPI(sck=m.Pin(25), mosi = m.Pin(26), miso = m.Pin(5)) +s.init() +cs = m.Pin(27) +cs.value(0) +cs.init(m.Pin.OUT, m.Pin.PULL_UP) +cs.value(1) +s.write(bytearray([0x80, 0x01] + [0xAA] * 1000)) +cs.value(0) + + +import machine as m +s = m.SPI(1, sck=m.Pin(25), mosi = m.Pin(26)) +s = m.SPI(1, sck=m.Pin(25), mosi = m.Pin(26), miso = m.Pin(5))) +s.transfer(bytearray((1,2,3,4,5))) +s.init(1, sck=m.Pin(25), mosi = m.Pin(26)) +cs = m.Pin(27) From 92129b5cde180551bf9b3c29b900136f90ffb2df Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 11:01:17 -0700 Subject: [PATCH 06/17] esp32/Makefile: updates for hw spi --- esp32/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp32/Makefile b/esp32/Makefile index 87063eb2d..b186aad40 100644 --- a/esp32/Makefile +++ b/esp32/Makefile @@ -129,6 +129,7 @@ SRC_C = \ modsocket.c \ modesp.c \ espneopixel.c \ + machine_hw_spi.c \ $(SRC_MOD) STM_SRC_C = $(addprefix stmhal/,\ @@ -203,6 +204,7 @@ ESPIDF_DRIVER_O = $(addprefix $(ESPCOMP)/driver/,\ spi_master.o \ gpio.o \ timer.o \ + spi_master.o \ rtc_module.o \ ) From 28cfb891f2989a95aeb0f0c0b1021a683f98ede5 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 11:03:50 -0700 Subject: [PATCH 07/17] esp32/machine_hw_spi.*: temporary delete to fix merging --- esp32/machine_hw_spi.c | 191 ----------------------------------------- esp32/machine_hw_spi.h | 49 ----------- esp32/scratch.txt | 39 --------- extmod/machine_spi.c | 1 + 4 files changed, 1 insertion(+), 279 deletions(-) delete mode 100644 esp32/machine_hw_spi.c delete mode 100644 esp32/machine_hw_spi.h delete mode 100644 esp32/scratch.txt diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c deleted file mode 100644 index 5306c820b..000000000 --- a/esp32/machine_hw_spi.c +++ /dev/null @@ -1,191 +0,0 @@ -/* -* This file is part of the MicroPython project, http://micropython.org/ -* -* The MIT License (MIT) -* -* Copyright (c) 2016 Damien P. George -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -#include -#include -#include - - -#include "py/runtime.h" -#include "py/stream.h" -#include "py/mphal.h" -#include "extmod/machine_spi.h" -#include "machine_hw_spi.h" -#include "modmachine.h" - - -// if a port didn't define MSB/LSB constants then provide them -#ifndef MICROPY_PY_MACHINE_SPI_MSB -#define MICROPY_PY_MACHINE_SPI_MSB (0) -#define MICROPY_PY_MACHINE_SPI_LSB (1) -#endif - - - -STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { - machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - int bits_to_send = len * self->bits; - if (self->deinitialized) { - return; - } - - struct spi_transaction_t transaction = { - .flags = 0, - .length = bits_to_send, - .tx_buffer = NULL, - .rx_buffer = NULL, - }; - bool shortMsg = len <= 4; - - - if(shortMsg) { - if (src != NULL) { - memcpy(&transaction.tx_data, src, len); - transaction.flags |= SPI_TRANS_USE_TXDATA; - } - if (dest != NULL) { - transaction.flags |= SPI_TRANS_USE_RXDATA; - } - } else { - transaction.tx_buffer = src; - transaction.rx_buffer = dest; - } - - spi_device_transmit(self->spi, &transaction); - - if (shortMsg && dest != NULL) { - memcpy(dest, &transaction.rx_data, len); - } -} - -/******************************************************************************/ -// MicroPython bindings for hw_spi - -STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "hw_spi(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", - self->host, self->baudrate, self->polarity, - self->phase, self->bits, self->firstbit, - self->sck, self->mosi, self->miso ); -} - -STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; - esp_err_t ret; - - enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 1} }, - { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, - { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, - { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} }, - { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), - allowed_args, args); - - int host = args[ARG_id].u_int; - if (host != HSPI_HOST && host != VSPI_HOST) { - mp_raise_ValueError("SPI ID must be either hw_spi(1) or VSPI(2)"); - } - - self->host = host; - self->baudrate = args[ARG_baudrate].u_int; - self->polarity = args[ARG_polarity].u_int ? 1 : 0; - self->phase = args[ARG_phase].u_int ? 1 : 0; - self->bits = args[ARG_bits].u_int; - self->firstbit = args[ARG_firstbit].u_int; - self->sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj); - self->miso = args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj); - self->mosi = args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj); - self->deinitialized = false; - - spi_bus_config_t buscfg = { - .miso_io_num = self->miso, - .mosi_io_num = self->mosi, - .sclk_io_num = self->sck, - .quadwp_io_num = -1, - .quadhd_io_num = -1 - }; - spi_device_interface_config_t devcfg = { - .clock_speed_hz = self->baudrate, - .mode = self->phase | (self->polarity << 1), - .spics_io_num = -1, // No CS pin - .queue_size = 1, - .flags = self->firstbit == MICROPY_PY_MACHINE_SPI_LSB ? SPI_DEVICE_TXBIT_LSBFIRST | SPI_DEVICE_RXBIT_LSBFIRST : 0, - .pre_cb = NULL - }; - - //Initialize the SPI bus - // FIXME: Does the DMA matter? There are two - ret = spi_bus_initialize(self->host, &buscfg, 1); - assert(ret == ESP_OK); - ret = spi_bus_add_device(self->host, &devcfg, &self->spi); - assert(ret == ESP_OK); -} - -STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; - esp_err_t ret; - if (!self->deinitialized) { - self->deinitialized = true; - ret = spi_bus_remove_device(self->spi); - assert(ret == ESP_OK); - ret = spi_bus_free(self->host); - assert(ret == ESP_OK); - } -} - -mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // args[0] holds the id of the peripheral - machine_hw_spi_obj_t *self = m_new_obj(machine_hw_spi_obj_t); - self->base.type = &machine_hw_spi_type; - // set defaults - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_hw_spi_init((mp_obj_base_t*)self, n_args, args, &kw_args); - return MP_OBJ_FROM_PTR(self); -} - -STATIC const mp_machine_spi_p_t machine_hw_spi_p = { - .init = machine_hw_spi_init, - .deinit = machine_hw_spi_deinit, - .transfer = machine_hw_spi_transfer, -}; - -const mp_obj_type_t machine_hw_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_hw_spi, - .print = machine_hw_spi_print, - .make_new = machine_hw_spi_make_new, - .protocol = &machine_hw_spi_p, - .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, -}; diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h deleted file mode 100644 index e6be895ec..000000000 --- a/esp32/machine_hw_spi.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* This file is part of the MicroPython project, http://micropython.org/ -* -* The MIT License (MIT) -* -* Copyright (c) 2016 Damien P. George -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -#ifndef MICROPY_INCLUDED_MACHINE_HW_SPI_H -#define MICROPY_INCLUDED_MACHINE_HW_SPI_H - -#include "driver/spi_master.h" - -typedef struct _machine_hw_spi_obj_t { - mp_obj_base_t base; - spi_host_device_t host; - uint32_t baudrate; - uint8_t polarity; - uint8_t phase; - uint8_t bits; - uint8_t firstbit; - int8_t sck; - int8_t mosi; - int8_t miso; - spi_device_handle_t spi; - bool deinitialized; -} machine_hw_spi_obj_t; - -extern const mp_obj_type_t machine_hw_spi_type ; - -#endif // MICROPY_INCLUDED_MACHINE_HW_SPI_H diff --git a/esp32/scratch.txt b/esp32/scratch.txt deleted file mode 100644 index e57e392bf..000000000 --- a/esp32/scratch.txt +++ /dev/null @@ -1,39 +0,0 @@ -import machine as m -p = m.Pin(4) -r = m.RTC() -p.init(p.IN, p.PULL_UP) -r.wake_on_ext0(pin = p, level = 0) -m.deepsleep() - -import machine as m -pins = (m.Pin(2), m.Pin(4)) -for p in pins: p.init(m.Pin.IN, m.Pin.PULL_UP) - -r = m.RTC() -r.wake_on_ext1(pins = pins, level = r.WAKEUP_ALL_LOW) -m.deepsleep() - - -import machine as m -r = m.RTC() -r.irq(trigger=r.ALARM0, wake=m.DEEPSLEEP) -r.alarm(r.ALARM0, 3000) -m.deepsleep() - -import machine as m -s = m.SPI(sck=m.Pin(25), mosi = m.Pin(26), miso = m.Pin(5)) -s.init() -cs = m.Pin(27) -cs.value(0) -cs.init(m.Pin.OUT, m.Pin.PULL_UP) -cs.value(1) -s.write(bytearray([0x80, 0x01] + [0xAA] * 1000)) -cs.value(0) - - -import machine as m -s = m.SPI(1, sck=m.Pin(25), mosi = m.Pin(26)) -s = m.SPI(1, sck=m.Pin(25), mosi = m.Pin(26), miso = m.Pin(5))) -s.transfer(bytearray((1,2,3,4,5))) -s.init(1, sck=m.Pin(25), mosi = m.Pin(26)) -cs = m.Pin(27) diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index a67d294ba..560cfc193 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -137,6 +137,7 @@ STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit); STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) { + printf("In machine_spi_transfer\n"); 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; spi_p->transfer(s, len, src, dest); From d3ecc015381eb880ac0c0de6c5b5b3554a5dc3e0 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 12:10:54 -0700 Subject: [PATCH 08/17] extmod/machine_spi.c: reverted --- esp32/machine_hw_spi.c | 191 +++++++++++++++++++++++++++++++++++++++++ esp32/machine_hw_spi.h | 49 +++++++++++ extmod/machine_spi.c | 1 - 3 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 esp32/machine_hw_spi.c create mode 100644 esp32/machine_hw_spi.h diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c new file mode 100644 index 000000000..5306c820b --- /dev/null +++ b/esp32/machine_hw_spi.c @@ -0,0 +1,191 @@ +/* +* This file is part of the MicroPython project, http://micropython.org/ +* +* The MIT License (MIT) +* +* Copyright (c) 2016 Damien P. George +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include +#include +#include + + +#include "py/runtime.h" +#include "py/stream.h" +#include "py/mphal.h" +#include "extmod/machine_spi.h" +#include "machine_hw_spi.h" +#include "modmachine.h" + + +// if a port didn't define MSB/LSB constants then provide them +#ifndef MICROPY_PY_MACHINE_SPI_MSB +#define MICROPY_PY_MACHINE_SPI_MSB (0) +#define MICROPY_PY_MACHINE_SPI_LSB (1) +#endif + + + +STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + int bits_to_send = len * self->bits; + if (self->deinitialized) { + return; + } + + struct spi_transaction_t transaction = { + .flags = 0, + .length = bits_to_send, + .tx_buffer = NULL, + .rx_buffer = NULL, + }; + bool shortMsg = len <= 4; + + + if(shortMsg) { + if (src != NULL) { + memcpy(&transaction.tx_data, src, len); + transaction.flags |= SPI_TRANS_USE_TXDATA; + } + if (dest != NULL) { + transaction.flags |= SPI_TRANS_USE_RXDATA; + } + } else { + transaction.tx_buffer = src; + transaction.rx_buffer = dest; + } + + spi_device_transmit(self->spi, &transaction); + + if (shortMsg && dest != NULL) { + memcpy(dest, &transaction.rx_data, len); + } +} + +/******************************************************************************/ +// MicroPython bindings for hw_spi + +STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "hw_spi(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", + self->host, self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->sck, self->mosi, self->miso ); +} + +STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + esp_err_t ret; + + enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 1} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} }, + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), + allowed_args, args); + + int host = args[ARG_id].u_int; + if (host != HSPI_HOST && host != VSPI_HOST) { + mp_raise_ValueError("SPI ID must be either hw_spi(1) or VSPI(2)"); + } + + self->host = host; + self->baudrate = args[ARG_baudrate].u_int; + self->polarity = args[ARG_polarity].u_int ? 1 : 0; + self->phase = args[ARG_phase].u_int ? 1 : 0; + self->bits = args[ARG_bits].u_int; + self->firstbit = args[ARG_firstbit].u_int; + self->sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj); + self->miso = args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj); + self->mosi = args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj); + self->deinitialized = false; + + spi_bus_config_t buscfg = { + .miso_io_num = self->miso, + .mosi_io_num = self->mosi, + .sclk_io_num = self->sck, + .quadwp_io_num = -1, + .quadhd_io_num = -1 + }; + spi_device_interface_config_t devcfg = { + .clock_speed_hz = self->baudrate, + .mode = self->phase | (self->polarity << 1), + .spics_io_num = -1, // No CS pin + .queue_size = 1, + .flags = self->firstbit == MICROPY_PY_MACHINE_SPI_LSB ? SPI_DEVICE_TXBIT_LSBFIRST | SPI_DEVICE_RXBIT_LSBFIRST : 0, + .pre_cb = NULL + }; + + //Initialize the SPI bus + // FIXME: Does the DMA matter? There are two + ret = spi_bus_initialize(self->host, &buscfg, 1); + assert(ret == ESP_OK); + ret = spi_bus_add_device(self->host, &devcfg, &self->spi); + assert(ret == ESP_OK); +} + +STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + esp_err_t ret; + if (!self->deinitialized) { + self->deinitialized = true; + ret = spi_bus_remove_device(self->spi); + assert(ret == ESP_OK); + ret = spi_bus_free(self->host); + assert(ret == ESP_OK); + } +} + +mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // args[0] holds the id of the peripheral + machine_hw_spi_obj_t *self = m_new_obj(machine_hw_spi_obj_t); + self->base.type = &machine_hw_spi_type; + // set defaults + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + machine_hw_spi_init((mp_obj_base_t*)self, n_args, args, &kw_args); + return MP_OBJ_FROM_PTR(self); +} + +STATIC const mp_machine_spi_p_t machine_hw_spi_p = { + .init = machine_hw_spi_init, + .deinit = machine_hw_spi_deinit, + .transfer = machine_hw_spi_transfer, +}; + +const mp_obj_type_t machine_hw_spi_type = { + { &mp_type_type }, + .name = MP_QSTR_hw_spi, + .print = machine_hw_spi_print, + .make_new = machine_hw_spi_make_new, + .protocol = &machine_hw_spi_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, +}; diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h new file mode 100644 index 000000000..e6be895ec --- /dev/null +++ b/esp32/machine_hw_spi.h @@ -0,0 +1,49 @@ +/* +* This file is part of the MicroPython project, http://micropython.org/ +* +* The MIT License (MIT) +* +* Copyright (c) 2016 Damien P. George +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#ifndef MICROPY_INCLUDED_MACHINE_HW_SPI_H +#define MICROPY_INCLUDED_MACHINE_HW_SPI_H + +#include "driver/spi_master.h" + +typedef struct _machine_hw_spi_obj_t { + mp_obj_base_t base; + spi_host_device_t host; + uint32_t baudrate; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + uint8_t firstbit; + int8_t sck; + int8_t mosi; + int8_t miso; + spi_device_handle_t spi; + bool deinitialized; +} machine_hw_spi_obj_t; + +extern const mp_obj_type_t machine_hw_spi_type ; + +#endif // MICROPY_INCLUDED_MACHINE_HW_SPI_H diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c index 560cfc193..a67d294ba 100644 --- a/extmod/machine_spi.c +++ b/extmod/machine_spi.c @@ -137,7 +137,6 @@ STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit); STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) { - printf("In machine_spi_transfer\n"); 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; spi_p->transfer(s, len, src, dest); From d0c792cc3367d86b9ebce1c0bf1b4edc13cf85a9 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 12:11:53 -0700 Subject: [PATCH 09/17] esp32/Makefile: removed redundant object files --- esp32/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/esp32/Makefile b/esp32/Makefile index b186aad40..746720ce5 100644 --- a/esp32/Makefile +++ b/esp32/Makefile @@ -122,7 +122,6 @@ SRC_C = \ machine_pin.c \ machine_touchpad.c \ machine_adc.c \ - machine_hw_spi.c \ machine_dac.c \ modmachine.c \ modnetwork.c \ @@ -201,7 +200,6 @@ ESPIDF_DRIVER_O = $(addprefix $(ESPCOMP)/driver/,\ uart.o \ periph_ctrl.o \ ledc.o \ - spi_master.o \ gpio.o \ timer.o \ spi_master.o \ From c6af5a76a60b0974e28c962568ac5506c216c95d Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Fri, 31 Mar 2017 12:12:20 -0700 Subject: [PATCH 10/17] esp32/machine_hw_spi.*: Updated to make spi_obj.init(...) idiom work --- esp32/machine_hw_spi.c | 322 +++++++++++++++++++++++++++++++---------- esp32/machine_hw_spi.h | 53 +++---- 2 files changed, 274 insertions(+), 101 deletions(-) diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 5306c820b..5caec1373 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -1,28 +1,28 @@ /* -* This file is part of the MicroPython project, http://micropython.org/ -* -* The MIT License (MIT) -* -* Copyright (c) 2016 Damien P. George -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -43,12 +43,45 @@ #define MICROPY_PY_MACHINE_SPI_LSB (1) #endif +#define MACHINE_HW_SPI_DEBUG_PRINTF(args...) printf(args) + +STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_handle_t* spi) { + + switch(spi_bus_remove_device(*spi)) { + case ESP_ERR_INVALID_ARG: + mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + return; + + case ESP_ERR_INVALID_STATE: + mp_raise_msg(&mp_type_OSError, "SPI device already freed"); + return; + } + + switch(spi_bus_free(host)) { + case ESP_ERR_INVALID_ARG: + mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + return; + + case ESP_ERR_INVALID_STATE: + mp_raise_msg(&mp_type_OSError, "SPI bus already freed"); + return; + } +} + +STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + if (self->state == MACHINE_HW_SPI_STATE_INIT) { + self->state = MACHINE_HW_SPI_STATE_DEINIT; + machine_hw_spi_deinit_internal(self->host, &self->spi); + } +} STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); int bits_to_send = len * self->bits; - if (self->deinitialized) { + if (self->state == MACHINE_HW_SPI_STATE_DEINIT) { + mp_raise_msg(&mp_type_OSError, "Transfer on deinitialized SPI"); return; } @@ -86,47 +119,92 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "hw_spi(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", - self->host, self->baudrate, self->polarity, - self->phase, self->bits, self->firstbit, - self->sck, self->mosi, self->miso ); + mp_printf(print, "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", + self->host, self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->sck, self->mosi, self->miso ); } -STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; +STATIC void machine_hw_spi_init_internal( + machine_hw_spi_obj_t *self, + int8_t host, + int32_t baudrate, + int8_t polarity, + int8_t phase, + int8_t bits, + int8_t firstbit, + int8_t sck, + int8_t mosi, + int8_t miso) { + bool changed = false; + MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal(self, host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", host, baudrate, polarity, phase, bits, firstbit, sck, mosi, miso); + + + MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal old values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", self->host, self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, self->sck, self->mosi, self->miso); esp_err_t ret; + spi_host_device_t old_host = self->host; - enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 1} }, - { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, - { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, - { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} }, - { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), - allowed_args, args); + if (host != -1 && host != self->host) { + self->host = host; + changed = true; + } - int host = args[ARG_id].u_int; - if (host != HSPI_HOST && host != VSPI_HOST) { - mp_raise_ValueError("SPI ID must be either hw_spi(1) or VSPI(2)"); + if (baudrate != -1 && baudrate != self->baudrate) { + self->baudrate = baudrate; + changed = true; } - self->host = host; - self->baudrate = args[ARG_baudrate].u_int; - self->polarity = args[ARG_polarity].u_int ? 1 : 0; - self->phase = args[ARG_phase].u_int ? 1 : 0; - self->bits = args[ARG_bits].u_int; - self->firstbit = args[ARG_firstbit].u_int; - self->sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj); - self->miso = args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj); - self->mosi = args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj); - self->deinitialized = false; + if (polarity != -1 && polarity != self->polarity) { + self->polarity = polarity; + changed = true; + } + + if (phase != -1 && phase != self->phase) { + self->phase = phase; + changed = true; + } + + if (bits != -1 && bits != self->bits) { + self->bits = bits; + changed = true; + } + + if (firstbit != -1 && firstbit != self->firstbit) { + self->firstbit = firstbit; + changed = true; + } + + if (sck != -2 && sck != self->sck) { + self->sck = sck; + changed = true; + } + + if (mosi != -2 && mosi != self->mosi) { + self->mosi = mosi; + changed = true; + } + + if (miso != -2 && miso != self->miso) { + self->miso = miso; + changed = true; + } + + if (self->host != HSPI_HOST && self->host != VSPI_HOST) { + mp_raise_ValueError("SPI ID must be either HSPI(1) or VSPI(2)"); + } + + if (changed) { + if (self->state == MACHINE_HW_SPI_STATE_INIT) { + MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal calling deinit()\n"); + self->state = MACHINE_HW_SPI_STATE_DEINIT; + machine_hw_spi_deinit_internal(old_host, &self->spi); + } + } else { + return; // no changes + } + + MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal new values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", self->host, self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, self->sck, self->mosi, self->miso); + spi_bus_config_t buscfg = { .miso_io_num = self->miso, @@ -135,6 +213,7 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ .quadwp_io_num = -1, .quadhd_io_num = -1 }; + spi_device_interface_config_t devcfg = { .clock_speed_hz = self->baudrate, .mode = self->phase | (self->polarity << 1), @@ -146,32 +225,123 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ //Initialize the SPI bus // FIXME: Does the DMA matter? There are two + ret = spi_bus_initialize(self->host, &buscfg, 1); - assert(ret == ESP_OK); + switch (ret) { + case ESP_ERR_INVALID_ARG: + mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + return; + + case ESP_ERR_INVALID_STATE: + mp_raise_msg(&mp_type_OSError, "SPI device already in use"); + return; + } + ret = spi_bus_add_device(self->host, &devcfg, &self->spi); - assert(ret == ESP_OK); + switch (ret) { + case ESP_ERR_INVALID_ARG: + mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + spi_bus_free(self->host); + return; + + case ESP_ERR_NO_MEM: + mp_raise_msg(&mp_type_OSError, "Out of memory"); + spi_bus_free(self->host); + return; + + case ESP_ERR_NOT_FOUND: + mp_raise_msg(&mp_type_OSError, "No free CS slots"); + spi_bus_free(self->host); + return; + } + self->state = MACHINE_HW_SPI_STATE_INIT; + MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal() returning\n"); } -STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { +STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; - esp_err_t ret; - if (!self->deinitialized) { - self->deinitialized = true; - ret = spi_bus_remove_device(self->spi); - assert(ret == ESP_OK); - ret = spi_bus_free(self->host); - assert(ret == ESP_OK); + + enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = -1} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), + allowed_args, args); + int8_t sck, mosi, miso; + + if(args[ARG_sck].u_obj == MP_OBJ_NULL) { + sck = -2; + } else if (args[ARG_sck].u_obj == mp_const_none) { + sck = -1; + } else { + sck = machine_pin_get_id(args[ARG_sck].u_obj); + } + + if(args[ARG_miso].u_obj == MP_OBJ_NULL) { + miso = -2; + } else if (args[ARG_miso].u_obj == mp_const_none) { + miso = -1; + } else { + miso = machine_pin_get_id(args[ARG_miso].u_obj); + } + + if(args[ARG_mosi].u_obj == MP_OBJ_NULL) { + mosi = -2; + } else if (args[ARG_mosi].u_obj == mp_const_none) { + mosi = -1; + } else { + mosi = machine_pin_get_id(args[ARG_mosi].u_obj); } + + MACHINE_HW_SPI_DEBUG_PRINTF ("before calling internal\n"); + machine_hw_spi_init_internal( self, args[ARG_id].u_int, args[ARG_baudrate].u_int, + args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int, + args[ARG_firstbit].u_int, sck, miso, mosi); } -mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // args[0] holds the id of the peripheral +mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = -1} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} }, + { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + machine_hw_spi_obj_t *self = m_new_obj(machine_hw_spi_obj_t); self->base.type = &machine_hw_spi_type; - // set defaults - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - machine_hw_spi_init((mp_obj_base_t*)self, n_args, args, &kw_args); + + machine_hw_spi_init_internal( + self, + args[ARG_id].u_int, + args[ARG_baudrate].u_int, + args[ARG_polarity].u_int, + args[ARG_phase].u_int, + args[ARG_bits].u_int, + args[ARG_firstbit].u_int, + args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj), + args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj), + args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj)); + return MP_OBJ_FROM_PTR(self); } @@ -183,7 +353,7 @@ STATIC const mp_machine_spi_p_t machine_hw_spi_p = { const mp_obj_type_t machine_hw_spi_type = { { &mp_type_type }, - .name = MP_QSTR_hw_spi, + .name = MP_QSTR_SPI, .print = machine_hw_spi_print, .make_new = machine_hw_spi_make_new, .protocol = &machine_hw_spi_p, diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h index e6be895ec..fbc6ca279 100644 --- a/esp32/machine_hw_spi.h +++ b/esp32/machine_hw_spi.h @@ -1,28 +1,28 @@ /* -* This file is part of the MicroPython project, http://micropython.org/ -* -* The MIT License (MIT) -* -* Copyright (c) 2016 Damien P. George -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_MACHINE_HW_SPI_H #define MICROPY_INCLUDED_MACHINE_HW_SPI_H @@ -41,7 +41,10 @@ typedef struct _machine_hw_spi_obj_t { int8_t mosi; int8_t miso; spi_device_handle_t spi; - bool deinitialized; + enum { + MACHINE_HW_SPI_STATE_NONE, + MACHINE_HW_SPI_STATE_INIT, + MACHINE_HW_SPI_STATE_DEINIT} state; } machine_hw_spi_obj_t; extern const mp_obj_type_t machine_hw_spi_type ; From 624a23cfb37834e3815f4660b76cbc2a5c1231d2 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 3 Apr 2017 10:29:41 -0700 Subject: [PATCH 11/17] esp32/Makefile: reverted FLASH_MODE to qio --- esp32/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp32/Makefile b/esp32/Makefile index 746720ce5..24243bace 100644 --- a/esp32/Makefile +++ b/esp32/Makefile @@ -16,7 +16,7 @@ include ../py/py.mk PORT ?= /dev/ttyUSB0 BAUD ?= 460800 -FLASH_MODE ?= dio +FLASH_MODE ?= qio FLASH_FREQ ?= 40m FLASH_SIZE ?= 4MB CROSS_COMPILE ?= xtensa-esp32-elf- From 57ce05063fda08a0411093ece0f4703087781780 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 3 Apr 2017 12:44:50 -0700 Subject: [PATCH 12/17] esp32/mahine_hw.*: copyright, reorg, now de-init resets pins to GPIO --- esp32/machine_hw_spi.c | 153 ++++++++++++++++++++--------------------- esp32/machine_hw_spi.h | 2 +- 2 files changed, 75 insertions(+), 80 deletions(-) diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 5caec1373..61fa47c6f 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2017 "Eric Poulsen" * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,6 @@ #include #include - #include "py/runtime.h" #include "py/stream.h" #include "py/mphal.h" @@ -36,18 +35,14 @@ #include "machine_hw_spi.h" #include "modmachine.h" - // if a port didn't define MSB/LSB constants then provide them #ifndef MICROPY_PY_MACHINE_SPI_MSB #define MICROPY_PY_MACHINE_SPI_MSB (0) #define MICROPY_PY_MACHINE_SPI_LSB (1) #endif -#define MACHINE_HW_SPI_DEBUG_PRINTF(args...) printf(args) - -STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_handle_t* spi) { - - switch(spi_bus_remove_device(*spi)) { +STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t * self) { + switch(spi_bus_remove_device(self->spi)) { case ESP_ERR_INVALID_ARG: mp_raise_msg(&mp_type_OSError, "Invalid configuration"); return; @@ -57,7 +52,7 @@ STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_ha return; } - switch(spi_bus_free(host)) { + switch(spi_bus_free(self->host)) { case ESP_ERR_INVALID_ARG: mp_raise_msg(&mp_type_OSError, "Invalid configuration"); return; @@ -66,65 +61,18 @@ STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_ha mp_raise_msg(&mp_type_OSError, "SPI bus already freed"); return; } -} - -STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; - if (self->state == MACHINE_HW_SPI_STATE_INIT) { - self->state = MACHINE_HW_SPI_STATE_DEINIT; - machine_hw_spi_deinit_internal(self->host, &self->spi); - } -} - - -STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { - machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - int bits_to_send = len * self->bits; - if (self->state == MACHINE_HW_SPI_STATE_DEINIT) { - mp_raise_msg(&mp_type_OSError, "Transfer on deinitialized SPI"); - return; - } - - struct spi_transaction_t transaction = { - .flags = 0, - .length = bits_to_send, - .tx_buffer = NULL, - .rx_buffer = NULL, - }; - bool shortMsg = len <= 4; + int8_t pins[3] = {self->miso, self->mosi, self->sck}; - if(shortMsg) { - if (src != NULL) { - memcpy(&transaction.tx_data, src, len); - transaction.flags |= SPI_TRANS_USE_TXDATA; + for (int i = 0; i < 3; i++) { + if (pins[i] != -1) { + gpio_pad_select_gpio(pins[i]); + gpio_matrix_out(pins[i], SIG_GPIO_OUT_IDX, false, false); + gpio_set_direction(pins[i], GPIO_MODE_INPUT); } - if (dest != NULL) { - transaction.flags |= SPI_TRANS_USE_RXDATA; - } - } else { - transaction.tx_buffer = src; - transaction.rx_buffer = dest; - } - - spi_device_transmit(self->spi, &transaction); - - if (shortMsg && dest != NULL) { - memcpy(dest, &transaction.rx_data, len); } } -/******************************************************************************/ -// MicroPython bindings for hw_spi - -STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", - self->host, self->baudrate, self->polarity, - self->phase, self->bits, self->firstbit, - self->sck, self->mosi, self->miso ); -} - STATIC void machine_hw_spi_init_internal( machine_hw_spi_obj_t *self, int8_t host, @@ -136,13 +84,14 @@ STATIC void machine_hw_spi_init_internal( int8_t sck, int8_t mosi, int8_t miso) { - bool changed = false; - MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal(self, host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", host, baudrate, polarity, phase, bits, firstbit, sck, mosi, miso); + // if we're not initialized, then we're + // implicitly 'changed', since this is the init routine + bool changed = self->state != MACHINE_HW_SPI_STATE_INIT; - MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal old values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", self->host, self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, self->sck, self->mosi, self->miso); esp_err_t ret; - spi_host_device_t old_host = self->host; + + machine_hw_spi_obj_t old_self = *self; if (host != -1 && host != self->host) { self->host = host; @@ -195,17 +144,13 @@ STATIC void machine_hw_spi_init_internal( if (changed) { if (self->state == MACHINE_HW_SPI_STATE_INIT) { - MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal calling deinit()\n"); self->state = MACHINE_HW_SPI_STATE_DEINIT; - machine_hw_spi_deinit_internal(old_host, &self->spi); + machine_hw_spi_deinit_internal(&old_self); } } else { return; // no changes } - MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal new values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n", self->host, self->baudrate, self->polarity, self->phase, self->bits, self->firstbit, self->sck, self->mosi, self->miso); - - spi_bus_config_t buscfg = { .miso_io_num = self->miso, .mosi_io_num = self->mosi, @@ -255,7 +200,60 @@ STATIC void machine_hw_spi_init_internal( return; } self->state = MACHINE_HW_SPI_STATE_INIT; - MACHINE_HW_SPI_DEBUG_PRINTF("machine_hw_spi_init_internal() returning\n"); +} + +STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + if (self->state == MACHINE_HW_SPI_STATE_INIT) { + self->state = MACHINE_HW_SPI_STATE_DEINIT; + machine_hw_spi_deinit_internal(self); + } +} + +STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + + int bits_to_send = len * self->bits; + bool shortMsg = len <= 4; + + if (self->state == MACHINE_HW_SPI_STATE_DEINIT) { + mp_raise_msg(&mp_type_OSError, "Transfer on deinitialized SPI"); + return; + } + + struct spi_transaction_t transaction = { + .flags = 0, + .length = bits_to_send, + .tx_buffer = NULL, + .rx_buffer = NULL, + }; + + if(shortMsg) { + if (src != NULL) { + memcpy(&transaction.tx_data, src, len); + } + transaction.flags |= (SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA); + } else { + transaction.tx_buffer = src; + transaction.rx_buffer = dest; + } + + spi_device_transmit(self->spi, &transaction); + + if (shortMsg && dest != NULL) { + memcpy(dest, &transaction.rx_data, len); + } +} + +/******************************************************************************/ +// MicroPython bindings for hw_spi + +STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", + self->host, self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->sck, self->mosi, self->miso ); } STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -263,7 +261,7 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = -1} }, + { MP_QSTR_id, MP_ARG_INT , {.u_int = -1} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, @@ -274,8 +272,6 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; - - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -305,10 +301,9 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ mosi = machine_pin_get_id(args[ARG_mosi].u_obj); } - MACHINE_HW_SPI_DEBUG_PRINTF ("before calling internal\n"); machine_hw_spi_init_internal( self, args[ARG_id].u_int, args[ARG_baudrate].u_int, args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int, - args[ARG_firstbit].u_int, sck, miso, mosi); + args[ARG_firstbit].u_int, sck, mosi, miso); } mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -339,8 +334,8 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ args[ARG_bits].u_int, args[ARG_firstbit].u_int, args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj), - args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj), - args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj)); + args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj), + args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj)); return MP_OBJ_FROM_PTR(self); } diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h index fbc6ca279..408e78bd8 100644 --- a/esp32/machine_hw_spi.h +++ b/esp32/machine_hw_spi.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2016 Damien P. George + * Copyright (c) 2017 "Eric Poulsen" * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 43ae202a6070a25f68d4c4f7085ed5798d1d5d78 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 3 Apr 2017 12:57:25 -0700 Subject: [PATCH 13/17] esp32/README.md: merged with upstream --- esp32/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esp32/README.md b/esp32/README.md index 30adb92ac..c2c3aa26b 100644 --- a/esp32/README.md +++ b/esp32/README.md @@ -160,9 +160,9 @@ import machine antenna = machine.Pin(16, machine.Pin.OUT, value=0) ``` - Troubleshooting --------------- -* Continuous reboots after programming: Ensure FLASH_MODE is correct for your board (e.g. ESP-WROOM-32 should be DIO). Perform a `make clean`, rebuild, redeploy. - +* Continuous reboots after programming: Ensure FLASH_MODE is correct for your + board (e.g. ESP-WROOM-32 should be DIO). Then perform a `make clean`, rebuild, + redeploy. From 3245dfa0a60c770237af2296a157f21c97cb2472 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 3 Apr 2017 21:24:09 -0700 Subject: [PATCH 14/17] esp32/machine_hw_spi.h: Deleted esp32/modmachine.h: Updated with machine_hw_spi_type esp32/machine_hw_spi.c: Added machine_hw_spi_type --- esp32/machine_hw_spi.c | 18 +++++++++++++++ esp32/machine_hw_spi.h | 52 ------------------------------------------ esp32/modmachine.h | 1 + 3 files changed, 19 insertions(+), 52 deletions(-) delete mode 100644 esp32/machine_hw_spi.h diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 61fa47c6f..2a7fd5597 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -41,6 +41,24 @@ #define MICROPY_PY_MACHINE_SPI_LSB (1) #endif +typedef struct _machine_hw_spi_obj_t { + mp_obj_base_t base; + spi_host_device_t host; + uint32_t baudrate; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + uint8_t firstbit; + int8_t sck; + int8_t mosi; + int8_t miso; + spi_device_handle_t spi; + enum { + MACHINE_HW_SPI_STATE_NONE, + MACHINE_HW_SPI_STATE_INIT, + MACHINE_HW_SPI_STATE_DEINIT} state; +} machine_hw_spi_obj_t; + STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t * self) { switch(spi_bus_remove_device(self->spi)) { case ESP_ERR_INVALID_ARG: diff --git a/esp32/machine_hw_spi.h b/esp32/machine_hw_spi.h deleted file mode 100644 index 408e78bd8..000000000 --- a/esp32/machine_hw_spi.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 "Eric Poulsen" - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_INCLUDED_MACHINE_HW_SPI_H -#define MICROPY_INCLUDED_MACHINE_HW_SPI_H - -#include "driver/spi_master.h" - -typedef struct _machine_hw_spi_obj_t { - mp_obj_base_t base; - spi_host_device_t host; - uint32_t baudrate; - uint8_t polarity; - uint8_t phase; - uint8_t bits; - uint8_t firstbit; - int8_t sck; - int8_t mosi; - int8_t miso; - spi_device_handle_t spi; - enum { - MACHINE_HW_SPI_STATE_NONE, - MACHINE_HW_SPI_STATE_INIT, - MACHINE_HW_SPI_STATE_DEINIT} state; -} machine_hw_spi_obj_t; - -extern const mp_obj_type_t machine_hw_spi_type ; - -#endif // MICROPY_INCLUDED_MACHINE_HW_SPI_H diff --git a/esp32/modmachine.h b/esp32/modmachine.h index 18ad57a62..fadc4afe1 100644 --- a/esp32/modmachine.h +++ b/esp32/modmachine.h @@ -7,5 +7,6 @@ extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_touchpad_type; extern const mp_obj_type_t machine_adc_type; extern const mp_obj_type_t machine_dac_type; +extern const mp_obj_type_t machine_hw_spi_type; #endif // MICROPY_INCLUDED_ESP32_MODMACHINE_H From 0cf672eee293db6405e3e4a3567cd185b8075231 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Mon, 3 Apr 2017 21:48:28 -0700 Subject: [PATCH 15/17] esp32/machine_hw_spi.c: Added include for 'driver/spi_master.h' --- esp32/machine_hw_spi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 2a7fd5597..b723c7e81 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -32,9 +32,10 @@ #include "py/stream.h" #include "py/mphal.h" #include "extmod/machine_spi.h" -#include "machine_hw_spi.h" #include "modmachine.h" +#include "driver/spi_master.h" + // if a port didn't define MSB/LSB constants then provide them #ifndef MICROPY_PY_MACHINE_SPI_MSB #define MICROPY_PY_MACHINE_SPI_MSB (0) From 471a9081911f109e6b154d7edd3639992564a9ba Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Tue, 4 Apr 2017 09:56:59 -0700 Subject: [PATCH 16/17] esp32/machine_hw_spi.c: Code and error message formatting --- esp32/machine_hw_spi.c | 103 +++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index b723c7e81..096f61bc7 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -55,15 +55,16 @@ typedef struct _machine_hw_spi_obj_t { int8_t miso; spi_device_handle_t spi; enum { - MACHINE_HW_SPI_STATE_NONE, - MACHINE_HW_SPI_STATE_INIT, - MACHINE_HW_SPI_STATE_DEINIT} state; + MACHINE_HW_SPI_STATE_NONE, + MACHINE_HW_SPI_STATE_INIT, + MACHINE_HW_SPI_STATE_DEINIT + } state; } machine_hw_spi_obj_t; -STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t * self) { - switch(spi_bus_remove_device(self->spi)) { +STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self) { + switch (spi_bus_remove_device(self->spi)) { case ESP_ERR_INVALID_ARG: - mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + mp_raise_msg(&mp_type_OSError, "invalid configuration"); return; case ESP_ERR_INVALID_STATE: @@ -71,9 +72,9 @@ STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t * self) { return; } - switch(spi_bus_free(self->host)) { + switch (spi_bus_free(self->host)) { case ESP_ERR_INVALID_ARG: - mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + mp_raise_msg(&mp_type_OSError, "invalid configuration"); return; case ESP_ERR_INVALID_STATE: @@ -93,18 +94,18 @@ STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t * self) { } STATIC void machine_hw_spi_init_internal( - machine_hw_spi_obj_t *self, - int8_t host, - int32_t baudrate, - int8_t polarity, - int8_t phase, - int8_t bits, - int8_t firstbit, - int8_t sck, - int8_t mosi, - int8_t miso) { - - // if we're not initialized, then we're + machine_hw_spi_obj_t *self, + int8_t host, + int32_t baudrate, + int8_t polarity, + int8_t phase, + int8_t bits, + int8_t firstbit, + int8_t sck, + int8_t mosi, + int8_t miso) { + + // if we're not initialized, then we're // implicitly 'changed', since this is the init routine bool changed = self->state != MACHINE_HW_SPI_STATE_INIT; @@ -191,9 +192,9 @@ STATIC void machine_hw_spi_init_internal( // FIXME: Does the DMA matter? There are two ret = spi_bus_initialize(self->host, &buscfg, 1); - switch (ret) { + switch (ret) { case ESP_ERR_INVALID_ARG: - mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + mp_raise_msg(&mp_type_OSError, "invalid configuration"); return; case ESP_ERR_INVALID_STATE: @@ -202,19 +203,19 @@ STATIC void machine_hw_spi_init_internal( } ret = spi_bus_add_device(self->host, &devcfg, &self->spi); - switch (ret) { + switch (ret) { case ESP_ERR_INVALID_ARG: - mp_raise_msg(&mp_type_OSError, "Invalid configuration"); + mp_raise_msg(&mp_type_OSError, "invalid configuration"); spi_bus_free(self->host); return; case ESP_ERR_NO_MEM: - mp_raise_msg(&mp_type_OSError, "Out of memory"); + mp_raise_msg(&mp_type_OSError, "out of memory"); spi_bus_free(self->host); return; case ESP_ERR_NOT_FOUND: - mp_raise_msg(&mp_type_OSError, "No free CS slots"); + mp_raise_msg(&mp_type_OSError, "no free slots"); spi_bus_free(self->host); return; } @@ -222,7 +223,7 @@ STATIC void machine_hw_spi_init_internal( } STATIC void machine_hw_spi_deinit(mp_obj_base_t *self_in) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t *) self_in; if (self->state == MACHINE_HW_SPI_STATE_INIT) { self->state = MACHINE_HW_SPI_STATE_DEINIT; machine_hw_spi_deinit_internal(self); @@ -236,7 +237,7 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui bool shortMsg = len <= 4; if (self->state == MACHINE_HW_SPI_STATE_DEINIT) { - mp_raise_msg(&mp_type_OSError, "Transfer on deinitialized SPI"); + mp_raise_msg(&mp_type_OSError, "transfer on deinitialized SPI"); return; } @@ -247,7 +248,7 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui .rx_buffer = NULL, }; - if(shortMsg) { + if (shortMsg) { if (src != NULL) { memcpy(&transaction.tx_data, src, len); } @@ -270,13 +271,13 @@ STATIC void machine_hw_spi_transfer(mp_obj_base_t *self_in, size_t len, const ui STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_hw_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)", - self->host, self->baudrate, self->polarity, - self->phase, self->bits, self->firstbit, - self->sck, self->mosi, self->miso ); + self->host, self->baudrate, self->polarity, + self->phase, self->bits, self->firstbit, + self->sck, self->mosi, self->miso); } STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t*)self_in; + machine_hw_spi_obj_t *self = (machine_hw_spi_obj_t *) self_in; enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso }; static const mp_arg_t allowed_args[] = { @@ -293,10 +294,10 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), - allowed_args, args); + allowed_args, args); int8_t sck, mosi, miso; - if(args[ARG_sck].u_obj == MP_OBJ_NULL) { + if (args[ARG_sck].u_obj == MP_OBJ_NULL) { sck = -2; } else if (args[ARG_sck].u_obj == mp_const_none) { sck = -1; @@ -304,7 +305,7 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ sck = machine_pin_get_id(args[ARG_sck].u_obj); } - if(args[ARG_miso].u_obj == MP_OBJ_NULL) { + if (args[ARG_miso].u_obj == MP_OBJ_NULL) { miso = -2; } else if (args[ARG_miso].u_obj == mp_const_none) { miso = -1; @@ -312,7 +313,7 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ miso = machine_pin_get_id(args[ARG_miso].u_obj); } - if(args[ARG_mosi].u_obj == MP_OBJ_NULL) { + if (args[ARG_mosi].u_obj == MP_OBJ_NULL) { mosi = -2; } else if (args[ARG_mosi].u_obj == mp_const_none) { mosi = -1; @@ -320,9 +321,9 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_ mosi = machine_pin_get_id(args[ARG_mosi].u_obj); } - machine_hw_spi_init_internal( self, args[ARG_id].u_int, args[ARG_baudrate].u_int, - args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int, - args[ARG_firstbit].u_int, sck, mosi, miso); + machine_hw_spi_init_internal(self, args[ARG_id].u_int, args[ARG_baudrate].u_int, + args[ARG_polarity].u_int, args[ARG_phase].u_int, args[ARG_bits].u_int, + args[ARG_firstbit].u_int, sck, mosi, miso); } mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -345,16 +346,16 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_ self->base.type = &machine_hw_spi_type; machine_hw_spi_init_internal( - self, - args[ARG_id].u_int, - args[ARG_baudrate].u_int, - args[ARG_polarity].u_int, - args[ARG_phase].u_int, - args[ARG_bits].u_int, - args[ARG_firstbit].u_int, - args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj), - args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj), - args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj)); + self, + args[ARG_id].u_int, + args[ARG_baudrate].u_int, + args[ARG_polarity].u_int, + args[ARG_phase].u_int, + args[ARG_bits].u_int, + args[ARG_firstbit].u_int, + args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj), + args[ARG_mosi].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_mosi].u_obj), + args[ARG_miso].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_miso].u_obj)); return MP_OBJ_FROM_PTR(self); } @@ -371,5 +372,5 @@ const mp_obj_type_t machine_hw_spi_type = { .print = machine_hw_spi_print, .make_new = machine_hw_spi_make_new, .protocol = &machine_hw_spi_p, - .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, + .locals_dict = (mp_obj_dict_t *) &mp_machine_spi_locals_dict, }; From 2582f44f185599e55b51346b3c98389b9bf3fa71 Mon Sep 17 00:00:00 2001 From: Eric Poulsen Date: Tue, 4 Apr 2017 21:23:56 -0700 Subject: [PATCH 17/17] esp32/machine_hw_spi.c: Moved SPI constants to mpconfigport.h esp32/mpconfigport.h: Moved SPI constants to mpconfigport.h --- esp32/machine_hw_spi.c | 6 ------ esp32/mpconfigport.h | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/esp32/machine_hw_spi.c b/esp32/machine_hw_spi.c index 096f61bc7..437b620f5 100644 --- a/esp32/machine_hw_spi.c +++ b/esp32/machine_hw_spi.c @@ -36,12 +36,6 @@ #include "driver/spi_master.h" -// if a port didn't define MSB/LSB constants then provide them -#ifndef MICROPY_PY_MACHINE_SPI_MSB -#define MICROPY_PY_MACHINE_SPI_MSB (0) -#define MICROPY_PY_MACHINE_SPI_LSB (1) -#endif - typedef struct _machine_hw_spi_obj_t { mp_obj_base_t base; spi_host_device_t host; diff --git a/esp32/mpconfigport.h b/esp32/mpconfigport.h index 159aef0c4..7ee0fd54b 100644 --- a/esp32/mpconfigport.h +++ b/esp32/mpconfigport.h @@ -128,6 +128,9 @@ #define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hw_spi_make_new #define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0) #define MICROPY_PY_MACHINE_SPI_MAX_BAUDRATE (ets_get_cpu_frequency() * 1000000 / 200) // roughly +#define MICROPY_PY_MACHINE_SPI_MSB (0) +#define MICROPY_PY_MACHINE_SPI_LSB (1) + #define MICROPY_PY_USSL (1) #define MICROPY_SSL_MBEDTLS (1) #define MICROPY_PY_WEBSOCKET (0)