mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 13:01:10 +02:00
Compare commits
22 Commits
c72a3e528d
...
v1.24-rele
Author | SHA1 | Date | |
---|---|---|---|
|
ecfdd5d6f9 | ||
|
564ef28ad2 | ||
|
7118942a8c | ||
|
948863c0b8 | ||
|
33f50d4f20 | ||
|
eb0027b82f | ||
|
03bc561edb | ||
|
49b83ed44a | ||
|
4f4d683ea5 | ||
|
67f893852a | ||
|
20a6d82872 | ||
|
0c580f71ae | ||
|
4e78c611b4 | ||
|
159b54b7da | ||
|
c1a85bb6de | ||
|
72799f9973 | ||
|
164c549248 | ||
|
6f327684b7 | ||
|
a7d3bc2308 | ||
|
c0afff8f22 | ||
|
785c92df76 | ||
|
5c7ac55232 |
@@ -536,6 +536,10 @@ static mp_obj_t framebuf_ellipse(size_t n_args, const mp_obj_t *args_in) {
|
||||
} else {
|
||||
mask |= ELLIPSE_MASK_ALL;
|
||||
}
|
||||
if (args[2] == 0 && args[3] == 0) {
|
||||
setpixel_checked(self, args[0], args[1], args[4], mask & ELLIPSE_MASK_ALL);
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_int_t two_asquare = 2 * args[2] * args[2];
|
||||
mp_int_t two_bsquare = 2 * args[3] * args[3];
|
||||
mp_int_t x = args[2];
|
||||
|
@@ -1432,7 +1432,7 @@ static mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
||||
case IP_DROP_MEMBERSHIP: {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len != sizeof(ip_addr_t) * 2) {
|
||||
if (bufinfo.len != sizeof(MP_IGMP_IP_ADDR_TYPE) * 2) {
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
|
||||
|
@@ -60,6 +60,10 @@ typedef struct _network_cyw43_obj_t {
|
||||
static const network_cyw43_obj_t network_cyw43_wl_sta = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_STA };
|
||||
static const network_cyw43_obj_t network_cyw43_wl_ap = { { &mp_network_cyw43_type }, &cyw43_state, CYW43_ITF_AP };
|
||||
|
||||
// Avoid race conditions with callbacks by tracking the last up or down request
|
||||
// we have made for each interface.
|
||||
static bool if_active[2];
|
||||
|
||||
static void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
struct netif *netif = &self->cyw->netif[self->itf];
|
||||
@@ -122,6 +126,10 @@ static MP_DEFINE_CONST_FUN_OBJ_3(network_cyw43_ioctl_obj, network_cyw43_ioctl);
|
||||
/*******************************************************************************/
|
||||
// network API
|
||||
|
||||
static uint32_t get_country_code(void) {
|
||||
return CYW43_COUNTRY(mod_network_country_code[0], mod_network_country_code[1], 0);
|
||||
}
|
||||
|
||||
static mp_obj_t network_cyw43_deinit(mp_obj_t self_in) {
|
||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
cyw43_deinit(self->cyw);
|
||||
@@ -132,10 +140,11 @@ static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_deinit_obj, network_cyw43_deinit)
|
||||
static mp_obj_t network_cyw43_active(size_t n_args, const mp_obj_t *args) {
|
||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (n_args == 1) {
|
||||
return mp_obj_new_bool(cyw43_tcpip_link_status(self->cyw, self->itf));
|
||||
return mp_obj_new_bool(if_active[self->itf]);
|
||||
} else {
|
||||
uint32_t country = CYW43_COUNTRY(mod_network_country_code[0], mod_network_country_code[1], 0);
|
||||
cyw43_wifi_set_up(self->cyw, self->itf, mp_obj_is_true(args[1]), country);
|
||||
bool value = mp_obj_is_true(args[1]);
|
||||
cyw43_wifi_set_up(self->cyw, self->itf, value, get_country_code());
|
||||
if_active[self->itf] = value;
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
@@ -311,7 +320,17 @@ static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_disconnect_obj, network_cyw43_dis
|
||||
|
||||
static mp_obj_t network_cyw43_isconnected(mp_obj_t self_in) {
|
||||
network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(cyw43_tcpip_link_status(self->cyw, self->itf) == 3);
|
||||
bool result = (cyw43_tcpip_link_status(self->cyw, self->itf) == CYW43_LINK_UP);
|
||||
|
||||
if (result && self->itf == CYW43_ITF_AP) {
|
||||
// For AP we need to not only know if the link is up, but also if any stations
|
||||
// have associated.
|
||||
uint8_t mac_buf[6];
|
||||
int num_stas = 1;
|
||||
cyw43_wifi_ap_get_stas(self->cyw, &num_stas, mac_buf);
|
||||
result = num_stas > 0;
|
||||
}
|
||||
return mp_obj_new_bool(result);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(network_cyw43_isconnected_obj, network_cyw43_isconnected);
|
||||
|
||||
@@ -351,13 +370,15 @@ static mp_obj_t network_cyw43_status(size_t n_args, const mp_obj_t *args) {
|
||||
if (self->itf != CYW43_ITF_AP) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("AP required"));
|
||||
}
|
||||
int num_stas;
|
||||
uint8_t macs[32 * 6];
|
||||
static const unsigned mac_len = 6;
|
||||
static const unsigned max_stas = 32;
|
||||
int num_stas = max_stas;
|
||||
uint8_t macs[max_stas * mac_len];
|
||||
cyw43_wifi_ap_get_stas(self->cyw, &num_stas, macs);
|
||||
mp_obj_t list = mp_obj_new_list(num_stas, NULL);
|
||||
for (int i = 0; i < num_stas; ++i) {
|
||||
mp_obj_t tuple[1] = {
|
||||
mp_obj_new_bytes(&macs[i * 6], 6),
|
||||
mp_obj_new_bytes(&macs[i * mac_len], mac_len),
|
||||
};
|
||||
((mp_obj_list_t *)MP_OBJ_TO_PTR(list))->items[i] = mp_obj_new_tuple(1, tuple);
|
||||
}
|
||||
@@ -445,6 +466,10 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("can't specify pos and kw args"));
|
||||
}
|
||||
|
||||
// A number of these options only update buffers in memory, and
|
||||
// won't do anything until the interface is cycled down and back up
|
||||
bool cycle_active = false;
|
||||
|
||||
for (size_t i = 0; i < kwargs->alloc; ++i) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
||||
mp_map_elem_t *e = &kwargs->table[i];
|
||||
@@ -457,6 +482,7 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
}
|
||||
case MP_QSTR_channel: {
|
||||
cyw43_wifi_ap_set_channel(self->cyw, mp_obj_get_int(e->value));
|
||||
cycle_active = true;
|
||||
break;
|
||||
}
|
||||
case MP_QSTR_ssid:
|
||||
@@ -464,6 +490,7 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
size_t len;
|
||||
const char *str = mp_obj_str_get_data(e->value, &len);
|
||||
cyw43_wifi_ap_set_ssid(self->cyw, len, (const uint8_t *)str);
|
||||
cycle_active = true;
|
||||
break;
|
||||
}
|
||||
case MP_QSTR_monitor: {
|
||||
@@ -483,6 +510,7 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
}
|
||||
case MP_QSTR_security: {
|
||||
cyw43_wifi_ap_set_auth(self->cyw, mp_obj_get_int(e->value));
|
||||
cycle_active = true;
|
||||
break;
|
||||
}
|
||||
case MP_QSTR_key:
|
||||
@@ -490,6 +518,7 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
size_t len;
|
||||
const char *str = mp_obj_str_get_data(e->value, &len);
|
||||
cyw43_wifi_ap_set_password(self->cyw, len, (const uint8_t *)str);
|
||||
cycle_active = true;
|
||||
break;
|
||||
}
|
||||
case MP_QSTR_pm: {
|
||||
@@ -519,6 +548,13 @@ static mp_obj_t network_cyw43_config(size_t n_args, const mp_obj_t *args, mp_map
|
||||
}
|
||||
}
|
||||
|
||||
// If the interface is already active, cycle it down and up
|
||||
if (cycle_active && if_active[self->itf]) {
|
||||
uint32_t country = get_country_code();
|
||||
cyw43_wifi_set_up(self->cyw, self->itf, false, country);
|
||||
cyw43_wifi_set_up(self->cyw, self->itf, true, country);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,13 @@ static int mp_vfs_blockdev_call_rw(mp_obj_t *args, size_t block_num, size_t bloc
|
||||
if (ret == mp_const_none) {
|
||||
return 0;
|
||||
} else {
|
||||
// Some block devices return a bool indicating success, so
|
||||
// convert those to an errno integer code.
|
||||
if (ret == mp_const_true) {
|
||||
return 0;
|
||||
} else if (ret == mp_const_false) {
|
||||
return -MP_EIO;
|
||||
}
|
||||
// Block device functions are expected to return 0 on success
|
||||
// and negative integer on errors. Check for positive integer
|
||||
// results as some callers (i.e. littlefs) will produce corrupt
|
||||
|
@@ -36,6 +36,10 @@
|
||||
#include "esp_err.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include "esp_clk_tree.h"
|
||||
#endif
|
||||
|
||||
#define PWM_DBG(...)
|
||||
// #define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, "\n");
|
||||
|
||||
@@ -207,53 +211,79 @@ static void configure_channel(machine_pwm_obj_t *self) {
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary workaround for ledc_find_suitable_duty_resolution function only being added in IDF V5.2
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0)
|
||||
static uint32_t ledc_find_suitable_duty_resolution(uint32_t src_clk_freq, uint32_t timer_freq) {
|
||||
// This implementation is based on the one used in Micropython v1.23
|
||||
|
||||
// Find the highest bit resolution for the requested frequency
|
||||
unsigned int freq = src_clk_freq;
|
||||
|
||||
int divider = (freq + timer_freq / 2) / timer_freq; // rounded
|
||||
if (divider == 0) {
|
||||
divider = 1;
|
||||
}
|
||||
float f = (float)freq / divider; // actual frequency
|
||||
if (f <= 1.0) {
|
||||
f = 1.0;
|
||||
}
|
||||
freq = (unsigned int)roundf((float)freq / f);
|
||||
|
||||
unsigned int res = 0;
|
||||
for (; freq > 1; freq >>= 1) {
|
||||
++res;
|
||||
}
|
||||
if (res == 0) {
|
||||
res = 1;
|
||||
} else if (res > HIGHEST_PWM_RES) {
|
||||
// Limit resolution to HIGHEST_PWM_RES to match units of our duty
|
||||
res = HIGHEST_PWM_RES;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_config_t *timer) {
|
||||
esp_err_t err;
|
||||
if (freq != timer->freq_hz) {
|
||||
// Find the highest bit resolution for the requested frequency
|
||||
unsigned int i = APB_CLK_FREQ; // 80 MHz
|
||||
#if SOC_LEDC_SUPPORT_REF_TICK
|
||||
if (freq < EMPIRIC_FREQ) {
|
||||
i = REF_CLK_FREQ; // 1 MHz
|
||||
}
|
||||
#endif
|
||||
|
||||
int divider = (i + freq / 2) / freq; // rounded
|
||||
if (divider == 0) {
|
||||
divider = 1;
|
||||
}
|
||||
float f = (float)i / divider; // actual frequency
|
||||
if (f <= 1.0) {
|
||||
f = 1.0;
|
||||
}
|
||||
i = (unsigned int)roundf((float)i / f);
|
||||
|
||||
unsigned int res = 0;
|
||||
for (; i > 1; i >>= 1) {
|
||||
++res;
|
||||
}
|
||||
if (res == 0) {
|
||||
res = 1;
|
||||
} else if (res > HIGHEST_PWM_RES) {
|
||||
// Limit resolution to HIGHEST_PWM_RES to match units of our duty
|
||||
res = HIGHEST_PWM_RES;
|
||||
}
|
||||
|
||||
// Configure the new resolution and frequency
|
||||
timer->duty_resolution = res;
|
||||
// Configure the new frequency and resolution
|
||||
timer->freq_hz = freq;
|
||||
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||
|
||||
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||
timer->clk_cfg = LEDC_USE_PLL_DIV_CLK;
|
||||
#elif SOC_LEDC_SUPPORT_APB_CLOCK
|
||||
timer->clk_cfg = LEDC_USE_APB_CLK;
|
||||
#elif SOC_LEDC_SUPPORT_XTAL_CLOCK
|
||||
timer->clk_cfg = LEDC_USE_XTAL_CLK;
|
||||
#else
|
||||
timer->clk_cfg = LEDC_USE_APB_CLK;
|
||||
#error No supported PWM / LEDC clocks.
|
||||
#endif
|
||||
#if SOC_LEDC_SUPPORT_REF_TICK
|
||||
if (freq < EMPIRIC_FREQ) {
|
||||
timer->clk_cfg = LEDC_USE_REF_TICK;
|
||||
}
|
||||
#endif
|
||||
uint32_t src_clk_freq = 0;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
err = esp_clk_tree_src_get_freq_hz(timer->clk_cfg, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_freq);
|
||||
if (err != ESP_OK) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unable to query source clock frequency %d"), (int)timer->clk_cfg);
|
||||
}
|
||||
#else
|
||||
// Simplified fallback logic for IDF V5.0.x, for targets with APB only.
|
||||
src_clk_freq = APB_CLK_FREQ; // 80 MHz
|
||||
#if SOC_LEDC_SUPPORT_REF_TICK
|
||||
if (timer->clk_cfg == LEDC_USE_REF_TICK) {
|
||||
src_clk_freq = REF_CLK_FREQ; // 1 MHz
|
||||
}
|
||||
#endif // SOC_LEDC_SUPPORT_REF_TICK
|
||||
#endif // ESP_IDF_VERSION
|
||||
|
||||
timer->duty_resolution = ledc_find_suitable_duty_resolution(src_clk_freq, timer->freq_hz);
|
||||
|
||||
// Set frequency
|
||||
esp_err_t err = ledc_timer_config(timer);
|
||||
err = ledc_timer_config(timer);
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_FAIL) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unreachable frequency %d"), freq);
|
||||
|
@@ -29,12 +29,14 @@
|
||||
#include "modmachine.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if SOC_TOUCH_VERSION_1 // ESP32 only
|
||||
#include "driver/touch_pad.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#elif SOC_TOUCH_VERSION_2 // All other SoCs with touch, to date
|
||||
#include "driver/touch_sensor.h"
|
||||
#else
|
||||
#error "Unknown touch hardware version"
|
||||
#endif
|
||||
|
||||
typedef struct _mtp_obj_t {
|
||||
@@ -70,6 +72,8 @@ static const mtp_obj_t touchpad_obj[] = {
|
||||
{{&machine_touchpad_type}, GPIO_NUM_12, TOUCH_PAD_NUM12},
|
||||
{{&machine_touchpad_type}, GPIO_NUM_13, TOUCH_PAD_NUM13},
|
||||
{{&machine_touchpad_type}, GPIO_NUM_14, TOUCH_PAD_NUM14},
|
||||
#else
|
||||
#error "Please add GPIO mapping for this SoC"
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -92,17 +96,18 @@ static mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
|
||||
if (!initialized) {
|
||||
touch_pad_init();
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
touch_pad_fsm_start();
|
||||
#endif
|
||||
initialized = 1;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if SOC_TOUCH_VERSION_1
|
||||
esp_err_t err = touch_pad_config(self->touchpad_id, 0);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#elif SOC_TOUCH_VERSION_2
|
||||
esp_err_t err = touch_pad_config(self->touchpad_id);
|
||||
#endif
|
||||
if (err == ESP_OK) {
|
||||
#if SOC_TOUCH_VERSION_2
|
||||
touch_pad_fsm_start();
|
||||
#endif
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("Touch pad error"));
|
||||
@@ -110,10 +115,10 @@ static mp_obj_t mtp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
|
||||
|
||||
static mp_obj_t mtp_config(mp_obj_t self_in, mp_obj_t value_in) {
|
||||
mtp_obj_t *self = self_in;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if SOC_TOUCH_VERSION_1
|
||||
uint16_t value = mp_obj_get_int(value_in);
|
||||
esp_err_t err = touch_pad_config(self->touchpad_id, value);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#elif SOC_TOUCH_VERSION_2
|
||||
esp_err_t err = touch_pad_config(self->touchpad_id);
|
||||
#endif
|
||||
if (err == ESP_OK) {
|
||||
@@ -125,10 +130,10 @@ MP_DEFINE_CONST_FUN_OBJ_2(mtp_config_obj, mtp_config);
|
||||
|
||||
static mp_obj_t mtp_read(mp_obj_t self_in) {
|
||||
mtp_obj_t *self = self_in;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#if SOC_TOUCH_VERSION_1
|
||||
uint16_t value;
|
||||
esp_err_t err = touch_pad_read(self->touchpad_id, &value);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#elif SOC_TOUCH_VERSION_2
|
||||
uint32_t value;
|
||||
esp_err_t err = touch_pad_read_raw_data(self->touchpad_id, &value);
|
||||
#endif
|
||||
@@ -155,4 +160,4 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
||||
locals_dict, &mtp_locals_dict
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif // SOC_TOUCH_SENSOR_SUPPORTED
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include "esp_task.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_psram.h"
|
||||
|
||||
#include "py/cstack.h"
|
||||
@@ -237,6 +238,13 @@ void *esp_native_code_commit(void *buf, size_t len, void *reloc) {
|
||||
len = (len + 3) & ~3;
|
||||
size_t len_node = sizeof(native_code_node_t) + len;
|
||||
native_code_node_t *node = heap_caps_malloc(len_node, MALLOC_CAP_EXEC);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// Workaround for ESP-IDF bug https://github.com/espressif/esp-idf/issues/14835
|
||||
if (node != NULL && !esp_ptr_executable(node)) {
|
||||
free(node);
|
||||
node = NULL;
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||
if (node == NULL) {
|
||||
m_malloc_fail(len_node);
|
||||
}
|
||||
|
@@ -213,7 +213,7 @@ static int mdns_getaddrinfo(const char *host_str, const char *port_str,
|
||||
#endif // MICROPY_HW_ENABLE_MDNS_QUERIES
|
||||
|
||||
static void _getaddrinfo_inner(const mp_obj_t host, const mp_obj_t portx,
|
||||
const struct addrinfo *hints, struct addrinfo **res) {
|
||||
struct addrinfo *hints, struct addrinfo **res) {
|
||||
int retval = 0;
|
||||
|
||||
*res = NULL;
|
||||
@@ -235,6 +235,9 @@ static void _getaddrinfo_inner(const mp_obj_t host, const mp_obj_t portx,
|
||||
|
||||
MP_THREAD_GIL_EXIT();
|
||||
|
||||
// The ai_canonname field is used below, so set the hint.
|
||||
hints->ai_flags |= AI_CANONNAME;
|
||||
|
||||
#if MICROPY_HW_ENABLE_MDNS_QUERIES
|
||||
retval = mdns_getaddrinfo(host_str, port_str, hints, res);
|
||||
#endif
|
||||
@@ -264,7 +267,8 @@ static void _getaddrinfo_inner(const mp_obj_t host, const mp_obj_t portx,
|
||||
static void _socket_getaddrinfo(const mp_obj_t addrtuple, struct addrinfo **resp) {
|
||||
mp_obj_t *elem;
|
||||
mp_obj_get_array_fixed_n(addrtuple, 2, &elem);
|
||||
_getaddrinfo_inner(elem[0], elem[1], NULL, resp);
|
||||
struct addrinfo hints = { 0 };
|
||||
_getaddrinfo_inner(elem[0], elem[1], &hints, resp);
|
||||
}
|
||||
|
||||
static mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
|
@@ -549,21 +549,38 @@ static mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
|
||||
break;
|
||||
}
|
||||
case MP_QSTR_channel: {
|
||||
uint8_t primary;
|
||||
wifi_second_chan_t secondary;
|
||||
// Get the current value of secondary
|
||||
esp_exceptions(esp_wifi_get_channel(&primary, &secondary));
|
||||
primary = mp_obj_get_int(kwargs->table[i].value);
|
||||
esp_err_t err = esp_wifi_set_channel(primary, secondary);
|
||||
if (err == ESP_ERR_INVALID_ARG) {
|
||||
// May need to swap secondary channel above to below or below to above
|
||||
secondary = (
|
||||
(secondary == WIFI_SECOND_CHAN_ABOVE)
|
||||
? WIFI_SECOND_CHAN_BELOW
|
||||
: (secondary == WIFI_SECOND_CHAN_BELOW)
|
||||
uint8_t channel = mp_obj_get_int(kwargs->table[i].value);
|
||||
if (self->if_id == ESP_IF_WIFI_AP) {
|
||||
cfg.ap.channel = channel;
|
||||
} else {
|
||||
// This setting is only used to determine the
|
||||
// starting channel for a scan, so it can result in
|
||||
// slightly faster connection times.
|
||||
cfg.sta.channel = channel;
|
||||
|
||||
// This additional code to directly set the channel
|
||||
// on the STA interface is only relevant for ESP-NOW
|
||||
// (when there is no STA connection attempt.)
|
||||
uint8_t old_primary;
|
||||
wifi_second_chan_t secondary;
|
||||
// Get the current value of secondary
|
||||
esp_exceptions(esp_wifi_get_channel(&old_primary, &secondary));
|
||||
esp_err_t err = esp_wifi_set_channel(channel, secondary);
|
||||
if (err == ESP_ERR_INVALID_ARG) {
|
||||
// May need to swap secondary channel above to below or below to above
|
||||
secondary = (
|
||||
(secondary == WIFI_SECOND_CHAN_ABOVE)
|
||||
? WIFI_SECOND_CHAN_BELOW
|
||||
: (secondary == WIFI_SECOND_CHAN_BELOW)
|
||||
? WIFI_SECOND_CHAN_ABOVE
|
||||
: WIFI_SECOND_CHAN_NONE);
|
||||
esp_exceptions(esp_wifi_set_channel(primary, secondary));
|
||||
err = esp_wifi_set_channel(channel, secondary);
|
||||
}
|
||||
esp_exceptions(err);
|
||||
if (channel != old_primary) {
|
||||
// Workaround the ESP-IDF Wi-Fi stack sometimes taking a moment to change channels
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ void ticker_init0(void) {
|
||||
#else
|
||||
NRFX_IRQ_PRIORITY_SET(FastTicker_IRQn, 2);
|
||||
#endif
|
||||
m_num_of_slow_tickers = 0;
|
||||
|
||||
NRFX_IRQ_PRIORITY_SET(SlowTicker_IRQn, 3);
|
||||
|
||||
|
@@ -7,7 +7,7 @@ QSTR_DEFS = qstrdefsport.h
|
||||
include $(TOP)/py/py.mk
|
||||
include $(TOP)/extmod/extmod.mk
|
||||
|
||||
XCVERSION ?= 1.35
|
||||
XCVERSION ?= 2.10
|
||||
XC16 ?= /opt/microchip/xc16/v$(XCVERSION)
|
||||
CROSS_COMPILE ?= $(XC16)/bin/xc16-
|
||||
|
||||
@@ -31,7 +31,7 @@ CFLAGS += -O1 -DNDEBUG
|
||||
endif
|
||||
|
||||
LDFLAGS += --heap=0 -nostdlib -T $(XC16)/support/$(PARTFAMILY)/gld/p$(PART).gld -Map=$@.map --cref -p$(PART)
|
||||
LIBS += -L$(XC16)/lib -L$(XC16)/lib/$(PARTFAMILY) -lc -lm -lpic30
|
||||
LIBS += -L$(XC16)/lib -L$(XC16)/lib/$(PARTFAMILY) -lc99-elf -lm-elf -lc99-pic30-elf
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
|
@@ -93,7 +93,3 @@ typedef int mp_off_t;
|
||||
#define MICROPY_MPHALPORT_H "pic16bit_mphal.h"
|
||||
#define MICROPY_HW_BOARD_NAME "dsPICSK"
|
||||
#define MICROPY_HW_MCU_NAME "dsPIC33"
|
||||
|
||||
// XC16 toolchain doesn't seem to define these
|
||||
typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
|
13
py/misc.h
13
py/misc.h
@@ -380,6 +380,18 @@ static inline bool mp_check(bool value) {
|
||||
|
||||
// mp_int_t can be larger than long, i.e. Windows 64-bit, nan-box variants
|
||||
static inline uint32_t mp_clz_mpi(mp_int_t x) {
|
||||
#ifdef __XC16__
|
||||
mp_uint_t mask = MP_OBJ_WORD_MSBIT_HIGH;
|
||||
mp_uint_t zeroes = 0;
|
||||
while (mask != 0) {
|
||||
if (mask & (mp_uint_t)x) {
|
||||
break;
|
||||
}
|
||||
zeroes++;
|
||||
mask >>= 1;
|
||||
}
|
||||
return zeroes;
|
||||
#else
|
||||
MP_STATIC_ASSERT(sizeof(mp_int_t) == sizeof(long long)
|
||||
|| sizeof(mp_int_t) == sizeof(long));
|
||||
|
||||
@@ -389,6 +401,7 @@ static inline uint32_t mp_clz_mpi(mp_int_t x) {
|
||||
} else {
|
||||
return mp_clzll((unsigned long long)x);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_MISC_H
|
||||
|
@@ -31,7 +31,7 @@
|
||||
// are unavailable.
|
||||
#define MICROPY_VERSION_MAJOR 1
|
||||
#define MICROPY_VERSION_MINOR 24
|
||||
#define MICROPY_VERSION_MICRO 0
|
||||
#define MICROPY_VERSION_MICRO 1
|
||||
#define MICROPY_VERSION_PRERELEASE 0
|
||||
|
||||
// Combined version as a 32-bit number for convenience to allow version
|
||||
|
@@ -208,7 +208,7 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
|
||||
size_t offset = mp_get_index(self->base.type, deque_len(self), index, false);
|
||||
size_t index_val = self->i_get + offset;
|
||||
if (index_val > self->alloc) {
|
||||
if (index_val >= self->alloc) {
|
||||
index_val -= self->alloc;
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,13 @@
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
// Workaround a bug in recent MSVC where NAN is no longer constant.
|
||||
// (By redefining back to the previous MSVC definition of NAN)
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1942
|
||||
#undef NAN
|
||||
#define NAN (-(float)(((float)(1e+300 * 1e+300)) * 0.0F))
|
||||
#endif
|
||||
|
||||
typedef struct _mp_obj_float_t {
|
||||
mp_obj_base_t base;
|
||||
mp_float_t value;
|
||||
|
@@ -63,3 +63,18 @@ for x, y in (
|
||||
fbuf.fill(0)
|
||||
fbuf.ellipse(x, y, 6, 12, 0xAA, True)
|
||||
printbuf()
|
||||
|
||||
# Draw an ellipse with both radius 0
|
||||
fbuf.fill(0)
|
||||
fbuf.ellipse(15, 15, 0, 0, 0xFF, True)
|
||||
printbuf()
|
||||
|
||||
# Draw an ellipse with both radius 0 out of bounds
|
||||
fbuf.fill(0)
|
||||
fbuf.ellipse(45, 45, 0, 0, 0xFF, True)
|
||||
printbuf()
|
||||
|
||||
# Draw an ellipse with radius 0 and all sectors masked out
|
||||
fbuf.fill(0)
|
||||
fbuf.ellipse(15, 15, 0, 0, 0xFF, True, 0)
|
||||
printbuf()
|
||||
|
@@ -702,3 +702,99 @@ aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000
|
||||
aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000
|
||||
aaaaaaaaaaaaaaaaaaaaaa00000000000000000000000000000000000000
|
||||
-->8--
|
||||
--8<--
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000ff0000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
-->8--
|
||||
--8<--
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
-->8--
|
||||
--8<--
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000
|
||||
-->8--
|
||||
|
@@ -129,8 +129,15 @@ def _remote_path_basename(a):
|
||||
|
||||
def do_filesystem_cp(state, src, dest, multiple, check_hash=False):
|
||||
if dest.startswith(":"):
|
||||
dest_exists = state.transport.fs_exists(dest[1:])
|
||||
dest_isdir = dest_exists and state.transport.fs_isdir(dest[1:])
|
||||
dest_no_slash = dest.rstrip("/" + os.path.sep + (os.path.altsep or ""))
|
||||
dest_exists = state.transport.fs_exists(dest_no_slash[1:])
|
||||
dest_isdir = dest_exists and state.transport.fs_isdir(dest_no_slash[1:])
|
||||
|
||||
# A trailing / on dest forces it to be a directory.
|
||||
if dest != dest_no_slash:
|
||||
if not dest_isdir:
|
||||
raise CommandError("cp: destination is not a directory")
|
||||
dest = dest_no_slash
|
||||
else:
|
||||
dest_exists = os.path.exists(dest)
|
||||
dest_isdir = dest_exists and os.path.isdir(dest)
|
||||
|
@@ -547,7 +547,10 @@ def main():
|
||||
|
||||
return 0
|
||||
except CommandError as e:
|
||||
# Make sure existing stdout appears before the error message on stderr.
|
||||
sys.stdout.flush()
|
||||
print(f"{_PROG}: {e}", file=sys.stderr)
|
||||
sys.stderr.flush()
|
||||
return 1
|
||||
finally:
|
||||
do_disconnect(state)
|
||||
|
@@ -151,9 +151,9 @@ class Transport:
|
||||
while data:
|
||||
chunk = data[:chunk_size]
|
||||
self.exec("w(" + repr(chunk) + ")")
|
||||
written += len(chunk)
|
||||
data = data[len(chunk) :]
|
||||
if progress_callback:
|
||||
written += len(chunk)
|
||||
progress_callback(written, src_size)
|
||||
self.exec("f.close()")
|
||||
except TransportExecError as e:
|
||||
|
@@ -16,7 +16,7 @@ for t in $TESTS; do
|
||||
TMP=$(mktemp -d)
|
||||
echo -n "${t}: "
|
||||
# Strip CR and replace the random temp dir with a token.
|
||||
if env MPREMOTE=${MPREMOTE} TMP="${TMP}" "${t}" | tr -d '\r' | sed "s,${TMP},"'${TMP},g' > "${t}.out"; then
|
||||
if env MPREMOTE=${MPREMOTE} TMP="${TMP}" "${t}" 2>&1 | tr -d '\r' | sed "s,${TMP},"'${TMP},g' > "${t}.out"; then
|
||||
if diff "${t}.out" "${t}.exp" > /dev/null; then
|
||||
echo "OK"
|
||||
else
|
||||
|
@@ -66,6 +66,16 @@ $MPREMOTE resume cp "${TMP}/a.py" :aaa
|
||||
$MPREMOTE resume cp "${TMP}/a.py" :bbb/b.py
|
||||
$MPREMOTE resume cat :aaa/a.py bbb/b.py
|
||||
|
||||
# Test cp -f (force copy).
|
||||
echo -----
|
||||
$MPREMOTE resume cp -f "${TMP}/a.py" :aaa
|
||||
$MPREMOTE resume cat :aaa/a.py
|
||||
|
||||
# Test cp where the destination has a trailing /.
|
||||
echo -----
|
||||
$MPREMOTE resume cp "${TMP}/a.py" :aaa/
|
||||
$MPREMOTE resume cp "${TMP}/a.py" :aaa/a.py/ || echo "expect error"
|
||||
|
||||
echo -----
|
||||
$MPREMOTE resume rm :b.py c.py
|
||||
$MPREMOTE resume ls
|
||||
|
@@ -38,6 +38,16 @@ print("World")
|
||||
print("Hello")
|
||||
print("World")
|
||||
-----
|
||||
cp ${TMP}/a.py :aaa
|
||||
print("Hello")
|
||||
print("World")
|
||||
-----
|
||||
cp ${TMP}/a.py :aaa/
|
||||
Up to date: aaa/a.py
|
||||
cp ${TMP}/a.py :aaa/a.py/
|
||||
mpremote: cp: destination is not a directory
|
||||
expect error
|
||||
-----
|
||||
rm :b.py
|
||||
rm :c.py
|
||||
ls :
|
||||
|
Reference in New Issue
Block a user