Updated SPI module, bugs fixed

Refactored PWM module
Prebuilt firmwares available as one zip file
This commit is contained in:
loboris
2018-01-07 15:48:03 +01:00
parent edcb67f349
commit baab2076a2
24 changed files with 1972 additions and 184 deletions
+6
View File
@@ -25,3 +25,9 @@ patches/
sdkconfig
sdkconfig.old
_sdkconfig.saved
sdkconfig.fw_esp32
sdkconfig.fw_esp32_ota
sdkconfig.fw_psram
sdkconfig.fw_psram_ota
makefirmwares.sh
+1 -1
View File
@@ -44,7 +44,7 @@
#=======================
TOOLS_VER=ver20180103.id
TOOLS_VER=ver20180107.id
#=======================
# -----------------------------
@@ -80,34 +80,43 @@ extern uint8_t disp_used_spi_host;
int checkSPIBUS(int8_t bus, int8_t mosi, uint8_t miso, uint8_t sck)
{
if ((disp_used_spi_host > 0) && (MPy_SPIbus[disp_used_spi_host]->mosi_io_num >= 0)) return -3; // bus used by display driver
if (MPy_SPIbus[bus] == NULL) return -2; // bus not available
if (MPy_SPIbus[bus]->mosi_io_num < 0) return 1; // bus not configured, free to use
if (MPy_SPIbus[bus] == NULL) return -2; // bus not available
if (MPy_SPIbus[bus]->mosi_io_num < 0) return 1; // bus not configured, free to use
if ((mosi != MPy_SPIbus[bus]->mosi_io_num) ||
(miso != MPy_SPIbus[bus]->miso_io_num) ||
(sck != MPy_SPIbus[bus]->sclk_io_num)) return -1; // requested pins different than configured
return 0; // bus already configured with the same pins
(sck != MPy_SPIbus[bus]->sclk_io_num)) return -1; // requested pins different than configured
return 0; // bus already configured with the same pins
}
//--------------------------------------------------------------------
STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self)
//---------------------------------------------------------------------------------
STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self, int freebus)
{
spi_device_handle_t handle = self->spi.handle;
if (spi_bus_remove_device(handle) != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "error at deinitialization");
mp_raise_msg(&mp_type_OSError, "error removing spi device");
}
spi_host_t *host=(spi_host_t*)handle->host;
int i;
for (i=0; i<NO_CS; i++) {
if (host->device[i] != NULL) break;
}
if (freebus) {
// Check if spi buss can be freed
spi_host_t *host=(spi_host_t*)handle->host;
int i;
for (i=0; i<NO_CS; i++) {
if (host->device[i] != NULL) break;
}
if (i == NO_CS) {
// no more devices attached to host, free bus
spi_bus_free(self->host);
MPy_SPIbus[self->host]->sclk_io_num = -1;
MPy_SPIbus[self->host]->mosi_io_num = -1;
MPy_SPIbus[self->host]->miso_io_num = -1;
if (i == NO_CS) {
// no more devices attached to host, free bus
if (spi_bus_free(self->host) != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "error freeing spi host");
}
gpio_pad_select_gpio(MPy_SPIbus[self->host]->miso_io_num);
gpio_pad_select_gpio(MPy_SPIbus[self->host]->mosi_io_num);
gpio_pad_select_gpio(MPy_SPIbus[self->host]->sclk_io_num);
MPy_SPIbus[self->host]->sclk_io_num = -1;
MPy_SPIbus[self->host]->mosi_io_num = -1;
MPy_SPIbus[self->host]->miso_io_num = -1;
}
}
}
@@ -123,22 +132,38 @@ STATIC void machine_hw_spi_init_internal(
int8_t mosi,
int8_t miso,
int8_t cs,
int8_t duplex) {
int8_t duplex,
uint8_t new) {
// if we're not initialized, then we're implicitly 'changed', since this is the init routine
uint16_t changed = self->state != MACHINE_HW_SPI_STATE_INIT;
esp_err_t ret;
int bus_state = 0;
machine_hw_spi_obj_t old_self = *self;
machine_hw_spi_obj_t old_self;
machine_hw_spi_obj_t *pold_self;
if ((host > -1) && (host != self->host)) {
if (new) pold_self = self;
else {
memcpy(&old_self, self, sizeof(machine_hw_spi_obj_t));
pold_self = &old_self;
}
if (((mosi < 0) && (MPy_SPIbus[self->host]->mosi_io_num <0)) ||
((miso < 0) && (MPy_SPIbus[self->host]->miso_io_num <0)) ||
((sck < 0) && (MPy_SPIbus[self->host]->sclk_io_num <0))) {
mp_raise_ValueError("Error, not all spi pins given");
}
uint16_t changed = pold_self->state != MACHINE_HW_SPI_STATE_INIT;
if (host > -1) {
// Host initialization or host change
#if CONFIG_SPIRAM_SPEED_80M
if (host != HSPI_HOST) {
mp_raise_ValueError("SPI host must be HSPI(1)");
}
#else
if (host != HSPI_HOST && host != VSPI_HOST) {
if ((host != HSPI_HOST) && (host != VSPI_HOST)) {
mp_raise_ValueError("SPI host must be either HSPI(1) or VSPI(2)");
}
#endif
@@ -147,33 +172,70 @@ STATIC void machine_hw_spi_init_internal(
if (bus_state == -3) {
mp_raise_ValueError("SPI host already used by display driver");
}
else if (bus_state < 0) {
else if (bus_state == -1) {
mp_raise_ValueError("SPI host already used with different configuration");
}
self->host = host;
changed |= 0x0004;
else if (bus_state == -2) {
mp_raise_ValueError("SPI host not available");
}
if ((host != pold_self->host) || (bus_state != 0)) {
self->host = host;
changed |= 0x0004;
}
}
if ((baudrate > 0) && (baudrate != self->devcfg.clock_speed_hz)) {
if (baudrate == 0) {
mp_raise_ValueError("SPI baudrate must be >0");
if ((baudrate > 0) && (baudrate != pold_self->devcfg.clock_speed_hz)) {
// Speed changed
if ((baudrate <= 0) || (baudrate > 80000000)) {
mp_raise_ValueError("SPI baudrate must be >0 & <=80000000");
}
self->devcfg.clock_speed_hz = baudrate;
changed |= 0x0008;
}
if ((polarity > -1) && (polarity != self->polarity)) {
if ((polarity > -1) && (polarity != pold_self->polarity)) {
// Polarity changed
self->polarity = polarity & 1;
changed |= 0x0010;
}
if ((phase > -1) && (phase != self->phase)) {
if ((phase > -1) && (phase != pold_self->phase)) {
// Phase changed
self->phase = phase & 1;
changed |= 0x0020;
}
if ((firstbit > -1) && (firstbit != self->firstbit)) {
if ((firstbit > -1) && (firstbit != pold_self->firstbit)) {
self->firstbit = firstbit & 1;
changed |= 0x0040;
}
if (bus_state > 0) {
if ((cs > -1) && (cs != pold_self->spi.cs)) {
// Initialize CS
gpio_pad_select_gpio(cs);
gpio_set_direction(cs, GPIO_MODE_OUTPUT);
gpio_set_level(cs, 1);
self->spi.cs = cs;
changed |= 0x0400;
}
if ((duplex > -1) && (duplex != pold_self->duplex)) {
// Duplex changed
self->duplex = duplex & 1;
changed |= 0x0800;
}
if (!changed) return; // no configuration changes, return
if (pold_self->state == MACHINE_HW_SPI_STATE_INIT) {
// Remove device from spi host
self->state = MACHINE_HW_SPI_STATE_DEINIT;
machine_hw_spi_deinit_internal(pold_self, 0);
}
// Check if spi bus has to be initialized
if (MPy_SPIbus[self->host]->mosi_io_num < 0) {
// SPI bus not initialized
gpio_pad_select_gpio(miso);
gpio_pad_select_gpio(mosi);
gpio_pad_select_gpio(sck);
@@ -181,7 +243,7 @@ STATIC void machine_hw_spi_init_internal(
gpio_set_pull_mode(miso, GPIO_PULLUP_ONLY);
gpio_set_direction(mosi, GPIO_MODE_OUTPUT);
gpio_set_direction(sck, GPIO_MODE_OUTPUT);
// SPI bus is free
MPy_SPIbus[self->host]->sclk_io_num = sck;
MPy_SPIbus[self->host]->mosi_io_num = mosi;
MPy_SPIbus[self->host]->miso_io_num = miso;
@@ -194,28 +256,11 @@ STATIC void machine_hw_spi_init_internal(
mp_raise_msg(&mp_type_OSError, "error initializing spi bus");
return;
}
changed |= 0x1000;
}
if ((cs > -1) && (cs != self->spi.cs)) {
gpio_pad_select_gpio(cs);
gpio_set_direction(cs, GPIO_MODE_OUTPUT);
gpio_set_level(cs, 1);
self->spi.cs = cs;
changed |= 0x0400;
}
if ((duplex > -1) && (duplex != self->duplex)) {
self->duplex = duplex & 1;
changed |= 0x0800;
}
if (!changed) return; // no changes
if (self->state == MACHINE_HW_SPI_STATE_INIT) {
self->state = MACHINE_HW_SPI_STATE_DEINIT;
machine_hw_spi_deinit_internal(&old_self);
}
self->devcfg.spics_io_num = -1; // No hw CS pin, we use software CS handling
// No hw CS pin, we use software CS handling in this module
self->devcfg.spics_io_num = -1;
self->devcfg.mode = self->phase | (self->polarity << 1);
self->devcfg.flags = ((self->firstbit == MICROPY_PY_MACHINE_SPI_LSB) ? SPI_DEVICE_TXBIT_LSBFIRST | SPI_DEVICE_RXBIT_LSBFIRST : 0);
@@ -227,6 +272,14 @@ STATIC void machine_hw_spi_init_internal(
ret = spi_bus_add_device(self->host, &self->devcfg, &self->spi.handle);
if (ret == ESP_OK) {
ret = spi_device_select(&self->spi, 1);
if (ret != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "Error selecting device");
}
ret = spi_device_deselect(&self->spi);
if (ret != ESP_OK) {
mp_raise_msg(&mp_type_OSError, "Error deselecting device");
}
self->state = MACHINE_HW_SPI_STATE_INIT;
return;
}
@@ -255,7 +308,7 @@ STATIC mp_obj_t machine_hw_spi_deinit(mp_obj_t self_in)
machine_hw_spi_obj_t *self = self_in;
if (self->state == MACHINE_HW_SPI_STATE_INIT) {
self->state = MACHINE_HW_SPI_STATE_DEINIT;
machine_hw_spi_deinit_internal(self);
machine_hw_spi_deinit_internal(self, 1);
}
return mp_const_none;
}
@@ -269,10 +322,11 @@ STATIC void machine_hw_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_p
if (self->spi.cs < 0) sprintf(scs, "Not used");
else sprintf(scs, "%d", self->spi.cs);
mp_printf(print, "SPI([%s] spihost=%u, baudrate=%u, polarity=%u, phase=%u, firstbit=%s, sck=%d, mosi=%d, miso=%d, cs=%s, duplex=%s)",
(self->state == MACHINE_HW_SPI_STATE_INIT) ? "init" : "deinit", self->host,
spi_get_speed(&self->spi), self->polarity, self->phase, (self->firstbit) ? "LSB" : "MSB",
MPy_SPIbus[self->host]->sclk_io_num, MPy_SPIbus[self->host]->mosi_io_num, MPy_SPIbus[self->host]->miso_io_num, scs, (self->duplex) ? "True" : "False");
mp_printf(print, "SPI( %s\n spihost=%s (%s)\n baudrate=%u, polarity=%u, phase=%u, firstbit=%s, duplex=%s\n Pins: sck=%d, mosi=%d, miso=%d, cs=%s\n )",
(self->state == MACHINE_HW_SPI_STATE_INIT) ? "INITIALIZED" : "DEINITIALIZED",
(self->host == HSPI_HOST) ? "HSPI" : "VSPI", (MPy_SPIbus[self->host]->mosi_io_num < 0) ? "free" : "initialized",
spi_get_speed(&self->spi), self->polarity, self->phase, (self->firstbit) ? "LSB" : "MSB", (self->duplex) ? "True" : "False",
MPy_SPIbus[self->host]->sclk_io_num, MPy_SPIbus[self->host]->mosi_io_num, MPy_SPIbus[self->host]->miso_io_num, scs);
}
//------------------------------------------------------------------------------------------------
@@ -307,7 +361,7 @@ STATIC mp_obj_t machine_hw_spi_init(mp_uint_t n_args, const mp_obj_t *pos_args,
machine_hw_spi_init_internal(self, args[ARG_spihost].u_int, args[ARG_baudrate].u_int,
args[ARG_polarity].u_int, args[ARG_phase].u_int,
args[ARG_firstbit].u_int, sck, mosi, miso, cs, args[ARG_duplex].u_bool);
args[ARG_firstbit].u_int, sck, mosi, miso, cs, args[ARG_duplex].u_bool, 0);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_hw_spi_init_obj, 0, machine_hw_spi_init);
@@ -340,6 +394,7 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
memset(&self->devcfg, 0, sizeof(spi_device_interface_config_t));
self->spi.cs = -1;
self->spi.handle = NULL;
int8_t cs = -1;
if (args[ARG_cs].u_obj != MP_OBJ_NULL) cs = machine_pin_get_gpio(args[ARG_cs].u_obj);
@@ -354,7 +409,8 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
machine_pin_get_gpio(args[ARG_mosi].u_obj),
machine_pin_get_gpio(args[ARG_miso].u_obj),
cs,
args[ARG_duplex].u_bool);
args[ARG_duplex].u_bool,
1);
return MP_OBJ_FROM_PTR(self);
}
@@ -4,6 +4,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2016 Damien P. George
* Copyright (c) 2018 LoBo (https://github.com/loboris)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +24,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include "driver/ledc.h"
#include "esp_err.h"
@@ -30,8 +32,12 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "modmachine.h"
#include "machine_pin.h"
#include "mphalport.h"
// High speed mode
#define PWMODE (LEDC_HIGH_SPEED_MODE)
// Forward dec'l
extern const mp_obj_type_t machine_pwm_type;
@@ -40,50 +46,44 @@ typedef struct _esp32_pwm_obj_t {
gpio_num_t pin;
uint8_t active;
uint8_t channel;
uint8_t duty;
ledc_timer_config_t timer_cfg;
} esp32_pwm_obj_t;
// Which channel has which GPIO pin assigned?
// (-1 if not assigned)
STATIC int chan_gpio[LEDC_CHANNEL_MAX];
STATIC int chan_gpio[LEDC_CHANNEL_MAX/2];
// Params for PW operation
// 5khz
#define PWFREQ (5000)
// High speed mode
#define PWMODE (LEDC_HIGH_SPEED_MODE)
// 10-bit resolution (compatible with esp8266 PWM)
#define PWRES (LEDC_TIMER_10_BIT)
// Timer 1
#define PWTIMER (LEDC_TIMER_1)
// Config of timer upon which we run all PWM'ed GPIO pins
STATIC bool pwm_inited = false;
STATIC ledc_timer_config_t timer_cfg = {
.bit_num = PWRES,
.freq_hz = PWFREQ,
.speed_mode = PWMODE,
.timer_num = PWTIMER
};
STATIC void pwm_init(void) {
//----------------------------------------------------
STATIC int set_freq(esp32_pwm_obj_t *self, int newval)
{
int oval = self->timer_cfg.freq_hz;
int ores = self->timer_cfg.duty_resolution;
int dperc = (self->duty * 100) / (2 << self->timer_cfg.duty_resolution);
// Initial condition: no channels assigned
for (int x = 0; x < LEDC_CHANNEL_MAX; ++x) {
chan_gpio[x] = -1;
// Adjust duty resolution
int dres = 15;
while (newval > (80000000 / (1 << dres))) {
dres--;
if (dres == 0) break;
}
if (dres == 0) return 0;
// Init with default timer params
ledc_timer_config(&timer_cfg);
}
STATIC int set_freq(int newval) {
int oval = timer_cfg.freq_hz;
timer_cfg.freq_hz = newval;
if (ledc_timer_config(&timer_cfg) != ESP_OK) {
timer_cfg.freq_hz = oval;
self->timer_cfg.duty_resolution = dres;
self->timer_cfg.freq_hz = newval;
if (ledc_timer_config(&self->timer_cfg) != ESP_OK) {
self->timer_cfg.freq_hz = oval;
self->timer_cfg.duty_resolution = ores;
return 0;
}
if (dres != ores) {
// Adjust
int dval = (dperc * (2 << self->timer_cfg.duty_resolution)) / 100;
ledc_set_duty(PWMODE, self->channel, dval);
ledc_update_duty(PWMODE, self->channel);
}
return 1;
}
@@ -91,18 +91,24 @@ STATIC int set_freq(int newval) {
// MicroPython bindings for PWM
STATIC void esp32_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
//------------------------------------------------------------------------------------------
STATIC void esp32_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "PWM(%u", self->pin);
mp_printf(print, "PWM(pin: %u", self->pin);
if (self->active) {
mp_printf(print, ", freq=%u, duty=%u", timer_cfg.freq_hz,
ledc_get_duty(PWMODE, self->channel));
int duty = ledc_get_duty(PWMODE, self->channel);
int dperc = (duty * 100) / (1 << self->timer_cfg.duty_resolution);
mp_printf(print, ", freq=%u Hz, duty=%u%% [%d], duty resolution=%d bits, channel=%d",
ledc_get_freq(PWMODE, self->timer_cfg.timer_num), dperc, duty,
self->timer_cfg.duty_resolution, self->channel);
}
mp_printf(print, ")");
}
STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
//------------------------------------------------------------------------------------------------------------------
STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
enum { ARG_freq, ARG_duty };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} },
@@ -115,77 +121,103 @@ STATIC void esp32_pwm_init_helper(esp32_pwm_obj_t *self,
int channel;
int avail = -1;
// Find a free PWM channel, also spot if our pin is
// already mentioned.
for (channel = 0; channel < LEDC_CHANNEL_MAX; ++channel) {
if (chan_gpio[channel] == self->pin) {
break;
}
if ((avail == -1) && (chan_gpio[channel] == -1)) {
avail = channel;
}
}
if (channel >= LEDC_CHANNEL_MAX) {
if (avail == -1) {
mp_raise_ValueError("out of PWM channels");
}
channel = avail;
}
self->channel = channel;
if (self->channel >= LEDC_CHANNEL_MAX/2) {
// New PWM assignment, find a free PWM channel
for (channel = 0; channel < LEDC_CHANNEL_MAX/2; ++channel) {
if (chan_gpio[channel] == -1) {
avail = channel;
break;
}
}
// Check if pin already used
for (channel = 0; channel < LEDC_CHANNEL_MAX/2; ++channel) {
if (chan_gpio[channel] == self->pin) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %d already used for pwm", self->pin));
}
}
// Find a free PWM channel
for (channel = 0; channel < LEDC_CHANNEL_MAX/2; ++channel) {
if (chan_gpio[channel] == -1) {
avail = channel;
break;
}
}
if (avail == -1) {
mp_raise_ValueError("out of PWM channels");
}
self->channel = channel;
// New PWM assignment
self->active = 1;
if (chan_gpio[channel] == -1) {
ledc_channel_config_t cfg = {
.channel = channel,
.duty = (1 << PWRES) / 2,
.gpio_num = self->pin,
.intr_type = LEDC_INTR_DISABLE,
.speed_mode = PWMODE,
.timer_sel = PWTIMER,
};
if (ledc_channel_config(&cfg) != ESP_OK) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"PWM not supported on pin %d", self->pin));
}
chan_gpio[channel] = self->pin;
// Setup timer
self->active = 1;
if (chan_gpio[channel] == -1) {
// Init timer
self->timer_cfg.duty_resolution = LEDC_TIMER_12_BIT; // 12 bits duty resolution
self->timer_cfg.freq_hz = 5000; // 5 kHz frequency
self->timer_cfg.speed_mode = PWMODE;
self->timer_cfg.timer_num = channel;
if (ledc_timer_config(&self->timer_cfg) != ESP_OK) {
mp_raise_ValueError("Error configuring pwm timer");
}
self->duty = 50;
ledc_channel_config_t cfg = {
.channel = channel,
.duty = (1 << self->timer_cfg.duty_resolution) / 2, // 50%
.gpio_num = self->pin,
.intr_type = LEDC_INTR_DISABLE,
.speed_mode = PWMODE,
.timer_sel = channel,
};
if (ledc_channel_config(&cfg) != ESP_OK) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "PWM not supported on pin %d", self->pin));
}
chan_gpio[channel] = self->pin;
}
}
else channel = self->channel;
// Maybe change PWM timer
int tval = args[ARG_freq].u_int;
if (tval != -1) {
if (tval != timer_cfg.freq_hz) {
if (!set_freq(tval)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"Bad frequency %d", tval));
if (tval != self->timer_cfg.freq_hz) {
if (!set_freq(self, tval)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Bad frequency %d", tval));
}
}
}
// Set duty cycle?
int dval = args[ARG_duty].u_int;
if (dval != -1) {
dval &= ((1 << PWRES)-1);
int dperc = args[ARG_duty].u_int;
if (dperc != -1) {
if ((dperc < 0) || (dperc > 100)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Bad duty %d, use 0 ~ 100 (%%)", dperc));
}
// Calculate duty value
int dval = (dperc * (2 << self->timer_cfg.duty_resolution)) / 100;
ledc_set_duty(PWMODE, channel, dval);
ledc_update_duty(PWMODE, channel);
}
}
STATIC mp_obj_t esp32_pwm_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw, const mp_obj_t *args) {
//-------------------------------------------------------------------------------------------------------------
STATIC mp_obj_t esp32_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args)
{
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
gpio_num_t pin_id = machine_pin_get_id(args[0]);
gpio_num_t pin_id = machine_pin_get_gpio(args[0]);
// create PWM object from the given pin
esp32_pwm_obj_t *self = m_new_obj(esp32_pwm_obj_t);
self->base.type = &machine_pwm_type;
self->pin = pin_id;
self->active = 0;
self->channel = -1;
self->channel = LEDC_CHANNEL_MAX;
// start the PWM subsystem if it's not already running
if (!pwm_inited) {
pwm_init();
// Initial condition: no channels assigned
for (int x = 0; x < LEDC_CHANNEL_MAX/2; ++x) {
chan_gpio[x] = -1;
}
pwm_inited = true;
}
@@ -197,19 +229,22 @@ STATIC mp_obj_t esp32_pwm_make_new(const mp_obj_type_t *type,
return MP_OBJ_FROM_PTR(self);
}
STATIC mp_obj_t esp32_pwm_init(size_t n_args,
const mp_obj_t *args, mp_map_t *kw_args) {
//------------------------------------------------------------------------------------
STATIC mp_obj_t esp32_pwm_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
esp32_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(esp32_pwm_init_obj, 1, esp32_pwm_init);
STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in) {
//------------------------------------------------
STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
int chan = self->channel;
// Valid channel?
if ((chan >= 0) && (chan < LEDC_CHANNEL_MAX)) {
if ((chan >= 0) && (chan < LEDC_CHANNEL_MAX/2)) {
// Mark it unused, and tell the hardware to stop routing
chan_gpio[chan] = -1;
ledc_stop(PWMODE, chan, 0);
@@ -220,54 +255,89 @@ STATIC mp_obj_t esp32_pwm_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_pwm_deinit_obj, esp32_pwm_deinit);
STATIC mp_obj_t esp32_pwm_freq(size_t n_args, const mp_obj_t *args) {
//-----------------------------------------------------------------
STATIC mp_obj_t esp32_pwm_freq(size_t n_args, const mp_obj_t *args)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
if (n_args == 1) {
// get
return MP_OBJ_NEW_SMALL_INT(timer_cfg.freq_hz);
return MP_OBJ_NEW_SMALL_INT(self->timer_cfg.freq_hz);
}
// set
int tval = mp_obj_get_int(args[1]);
if (!set_freq(tval)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"Bad frequency %d", tval));
if (!set_freq(self, tval)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Bad frequency %d", tval));
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_freq_obj, 1, 2, esp32_pwm_freq);
STATIC mp_obj_t esp32_pwm_duty(size_t n_args, const mp_obj_t *args) {
//-----------------------------------------------------------------
STATIC mp_obj_t esp32_pwm_duty(size_t n_args, const mp_obj_t *args)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
int duty;
int dperc, duty;
if (n_args == 1) {
// get
// get duty
duty = ledc_get_duty(PWMODE, self->channel);
return MP_OBJ_NEW_SMALL_INT(duty);
dperc = (duty * 100) / (1 << self->timer_cfg.duty_resolution);
return MP_OBJ_NEW_SMALL_INT(dperc);
}
// set
duty = mp_obj_get_int(args[1]);
duty &= ((1 << PWRES)-1);
ledc_set_duty(PWMODE, self->channel, duty);
ledc_update_duty(PWMODE, self->channel);
dperc = mp_obj_get_int(args[1]);
if (dperc != -1) {
if ((dperc < 0) || (dperc > 100)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Bad duty %d, use 0 ~ 100 (%%)", dperc));
}
// Calculate duty value
duty = (dperc * (1 << self->timer_cfg.duty_resolution)) / 100;
ledc_set_duty(PWMODE, self->channel, duty);
ledc_update_duty(PWMODE, self->channel);
self->duty = dperc;
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_duty_obj,
1, 2, esp32_pwm_duty);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_duty_obj, 1, 2, esp32_pwm_duty);
//-----------------------------------------------
STATIC mp_obj_t esp32_pwm_pause(mp_obj_t self_in)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
ledc_timer_pause(PWMODE, self->timer_cfg.timer_num);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_pwm_pause_obj, esp32_pwm_pause);
//------------------------------------------------
STATIC mp_obj_t esp32_pwm_resume(mp_obj_t self_in)
{
esp32_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
ledc_timer_resume(PWMODE, self->timer_cfg.timer_num);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_pwm_resume_obj, esp32_pwm_resume);
//==============================================================
STATIC const mp_rom_map_elem_t esp32_pwm_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&esp32_pwm_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_pwm_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&esp32_pwm_freq_obj) },
{ MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&esp32_pwm_duty_obj) },
{ MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&esp32_pwm_pause_obj) },
{ MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&esp32_pwm_resume_obj) },
};
STATIC MP_DEFINE_CONST_DICT(esp32_pwm_locals_dict, esp32_pwm_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(esp32_pwm_locals_dict,
esp32_pwm_locals_dict_table);
//======================================
const mp_obj_type_t machine_pwm_type = {
{ &mp_type_type },
.name = MP_QSTR_PWM,
@@ -1,8 +1,8 @@
// MicroPython version info
#define MICROPY_GIT_TAG "ESP32_LoBo_v3.1.0"
#define MICROPY_GIT_HASH "g1837a034"
#define MICROPY_BUILD_DATE "2017-01-03"
#define MICROPY_GIT_TAG "ESP32_LoBo_v3.1.1"
#define MICROPY_GIT_HASH "ga1b59679"
#define MICROPY_BUILD_DATE "2017-01-07"
#define MICROPY_VERSION_MAJOR (3)
#define MICROPY_VERSION_MINOR (1)
#define MICROPY_VERSION_MICRO (0)
#define MICROPY_VERSION_STRING "3.1.0"
#define MICROPY_VERSION_MICRO (1)
#define MICROPY_VERSION_STRING "3.1.1"
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
# BUILD standard firmwares
mv -f sdkconfig sdkconfig.bkp
# Build firmwaware for esp32, no psRAM, no OTA
cp sdkconfig.fw_esp32 sdkconfig
./BUILD.sh -j8 clean all
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
./BUILD.sh -fs 1024 flash > /dev/null 2>&1
./BUILD.sh firmware
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
# Build firmwaware for esp32, no psRAM, OTA
cp sdkconfig.fw_esp32_ota sdkconfig
./BUILD.sh -j8 clean all
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
./BUILD.sh -fs 1024 flash > /dev/null 2>&1
./BUILD.sh firmware
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
# Build firmwaware for esp32, psRAM, no OTA
cp sdkconfig.fw_psram sdkconfig
./BUILD.sh -j8 clean all
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
./BUILD.sh -fs 1024 flash > /dev/null 2>&1
./BUILD.sh firmware
if [ $? -ne 0 ]; then
exit 1
fi
# Build firmwaware for esp32, psRAM, OTA
cp sdkconfig.fw_psram_ota sdkconfig
./BUILD.sh -j8 clean all
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
./BUILD.sh -fs 1024 flash > /dev/null 2>&1
./BUILD.sh firmware
if [ $? -ne 0 ]; then
mv -f sdkconfig.bkp sckconfig
exit 1
fi
mv -f sdkconfig.bkp sckconfig
cd firmware
rm -f MicroPython_LoBo_Firmwares.zip > /dev/null 2>&1
zip MicroPython_LoBo_Firmwares.zip -9 -r esp32 esp32_ota esp32_psram esp32_psram_ota README.md
cd ..

Some files were not shown because too many files have changed in this diff Show More