Merge remote-tracking branch 'adafruit/main' into update_tinyusb_abort
This commit is contained in:
commit
f4dba86f1c
@ -20,3 +20,7 @@ deques
|
|||||||
extint
|
extint
|
||||||
shs
|
shs
|
||||||
pass-thru
|
pass-thru
|
||||||
|
numer
|
||||||
|
arithmetics
|
||||||
|
ftbfs
|
||||||
|
straightaway
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
#all: Reformat remaining C code that doesn't have a space after a comma.
|
||||||
|
5b700b0af90591d6b1a2c087bb8de6b7f1bfdd2d
|
||||||
|
|
||||||
|
# ports: Reformat more C and Python source code.
|
||||||
|
5c32111fa0e31e451b0f1666bdf926be2fdfd82c
|
||||||
|
|
||||||
|
# all: Update Python formatting to latest Black version 22.1.0.
|
||||||
|
ab2923dfa1174dc177f0a90cb00a7e4ff87958d2
|
||||||
|
|
||||||
|
# all: Update Python formatting to latest Black version 21.12b0.
|
||||||
|
3770fab33449a5dadf8eb06edfae0767e75320a6
|
||||||
|
|
||||||
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
|
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
|
||||||
0f78c36c5aa458a954eed39a46942209107a553e
|
0f78c36c5aa458a954eed39a46942209107a553e
|
||||||
|
|
||||||
|
4
.github/workflows/run-tests.yml
vendored
4
.github/workflows/run-tests.yml
vendored
@ -55,13 +55,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make -C examples/natmod/features1
|
make -C examples/natmod/features1
|
||||||
make -C examples/natmod/features2
|
make -C examples/natmod/features2
|
||||||
make -C examples/natmod/btree
|
|
||||||
make -C examples/natmod/framebuf
|
|
||||||
make -C examples/natmod/uheapq
|
make -C examples/natmod/uheapq
|
||||||
make -C examples/natmod/urandom
|
make -C examples/natmod/urandom
|
||||||
make -C examples/natmod/ure
|
make -C examples/natmod/ure
|
||||||
make -C examples/natmod/uzlib
|
make -C examples/natmod/uzlib
|
||||||
- name: Test native modules
|
- name: Test native modules
|
||||||
if: matrix.test == 'all'
|
if: matrix.test == 'all'
|
||||||
run: ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py
|
run: ./run-natmodtests.py extmod/{uheapq*,ure*,uzlib*}.py
|
||||||
working-directory: tests
|
working-directory: tests
|
||||||
|
@ -235,7 +235,7 @@ litex alpha
|
|||||||
mimxrt10xx alpha
|
mimxrt10xx alpha
|
||||||
nrf stable
|
nrf stable
|
||||||
raspberrypi stable
|
raspberrypi stable
|
||||||
efr32 alpha
|
silabs (efr32) alpha
|
||||||
stm ``F4`` stable | ``others`` beta
|
stm ``F4`` stable | ``others`` beta
|
||||||
unix alpha
|
unix alpha
|
||||||
================ ============================================================
|
================ ============================================================
|
||||||
|
19
conf.py
19
conf.py
@ -266,19 +266,9 @@ rst_epilog = """
|
|||||||
|
|
||||||
# -- Options for HTML output ----------------------------------------------
|
# -- Options for HTML output ----------------------------------------------
|
||||||
|
|
||||||
# on_rtd is whether we are on readthedocs.org
|
import sphinx_rtd_theme
|
||||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
|
||||||
try:
|
|
||||||
import sphinx_rtd_theme
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
|
||||||
except:
|
|
||||||
html_theme = 'default'
|
|
||||||
html_theme_path = ['.']
|
|
||||||
else:
|
|
||||||
html_theme_path = ['.']
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
@ -441,8 +431,9 @@ texinfo_documents = [
|
|||||||
|
|
||||||
|
|
||||||
# Example configuration for intersphinx: refer to the Python standard library.
|
# Example configuration for intersphinx: refer to the Python standard library.
|
||||||
intersphinx_mapping = {"cpython": ('https://docs.python.org/3/', None),
|
intersphinx_mapping = {"python": ('https://docs.python.org/3/', None),
|
||||||
"register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),
|
"register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),
|
||||||
|
"mcp2515": ('https://circuitpython.readthedocs.io/projects/mcp2515/en/latest/', None),
|
||||||
"typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)}
|
"typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)}
|
||||||
|
|
||||||
# Adapted from sphinxcontrib-redirects
|
# Adapted from sphinxcontrib-redirects
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 427cc923976229bcb981ca6f218ebe8efd636df6
|
Subproject commit d17b999f46fd148ac192ad692b8a4639f81add38
|
@ -82,28 +82,23 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
|||||||
|
|
||||||
// Generic Access Service setup.
|
// Generic Access Service setup.
|
||||||
|
|
||||||
bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *generic_access_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
generic_access_service_uuid->base.type = &bleio_uuid_type;
|
|
||||||
common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL);
|
common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL);
|
||||||
|
|
||||||
bleio_uuid_obj_t *device_name_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *device_name_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
device_name_characteristic_uuid->base.type = &bleio_uuid_type;
|
|
||||||
common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL);
|
common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL);
|
||||||
|
|
||||||
bleio_uuid_obj_t *appearance_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *appearance_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
appearance_characteristic_uuid->base.type = &bleio_uuid_type;
|
|
||||||
common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
|
common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
|
||||||
|
|
||||||
// Not implemented:
|
// Not implemented:
|
||||||
// Peripheral Preferred Connection Parameters
|
// Peripheral Preferred Connection Parameters
|
||||||
// Central Address Resolution
|
// Central Address Resolution
|
||||||
|
|
||||||
bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t);
|
bleio_service_obj_t *generic_access_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||||
generic_access_service->base.type = &bleio_service_type;
|
|
||||||
common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false);
|
common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false);
|
||||||
|
|
||||||
adapter->device_name_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
adapter->device_name_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||||
adapter->device_name_characteristic->base.type = &bleio_characteristic_type;
|
|
||||||
|
|
||||||
char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
|
char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
|
||||||
mp_buffer_info_t generic_name_bufinfo = {
|
mp_buffer_info_t generic_name_bufinfo = {
|
||||||
@ -132,8 +127,7 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
|||||||
.len = sizeof(zero_16),
|
.len = sizeof(zero_16),
|
||||||
};
|
};
|
||||||
|
|
||||||
adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
adapter->appearance_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||||
adapter->appearance_characteristic->base.type = &bleio_characteristic_type;
|
|
||||||
|
|
||||||
common_hal_bleio_characteristic_construct(
|
common_hal_bleio_characteristic_construct(
|
||||||
adapter->appearance_characteristic,
|
adapter->appearance_characteristic,
|
||||||
@ -151,20 +145,16 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
|||||||
|
|
||||||
// Generic Attribute Service setup.
|
// Generic Attribute Service setup.
|
||||||
|
|
||||||
bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *generic_attribute_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
generic_attribute_service_uuid->base.type = &bleio_uuid_type;
|
|
||||||
common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL);
|
common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL);
|
||||||
|
|
||||||
bleio_uuid_obj_t *service_changed_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
bleio_uuid_obj_t *service_changed_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
service_changed_characteristic_uuid->base.type = &bleio_uuid_type;
|
|
||||||
common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL);
|
common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL);
|
||||||
|
|
||||||
bleio_service_obj_t *generic_attribute_service = m_new_obj(bleio_service_obj_t);
|
bleio_service_obj_t *generic_attribute_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||||
generic_attribute_service->base.type = &bleio_service_type;
|
|
||||||
common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false);
|
common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false);
|
||||||
|
|
||||||
adapter->service_changed_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
adapter->service_changed_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||||
adapter->service_changed_characteristic->base.type = &bleio_characteristic_type;
|
|
||||||
|
|
||||||
uint32_t zero_32 = 0;
|
uint32_t zero_32 = 0;
|
||||||
mp_buffer_info_t zero_32_value = {
|
mp_buffer_info_t zero_32_value = {
|
||||||
@ -416,8 +406,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s
|
|||||||
bt_addr_t addr;
|
bt_addr_t addr;
|
||||||
hci_check_error(hci_read_bd_addr(&addr));
|
hci_check_error(hci_read_bd_addr(&addr));
|
||||||
|
|
||||||
bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
|
bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type);
|
||||||
address->base.type = &bleio_address_type;
|
|
||||||
|
|
||||||
common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC);
|
common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC);
|
||||||
return address;
|
return address;
|
||||||
@ -490,7 +479,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t
|
|||||||
self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
|
self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
|
||||||
|
|
||||||
// size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
|
// size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
|
||||||
// uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false);
|
// uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size);
|
||||||
// ble_data_t * sd_data = (ble_data_t *) raw_data;
|
// ble_data_t * sd_data = (ble_data_t *) raw_data;
|
||||||
// self->scan_results->common_hal_data = sd_data;
|
// self->scan_results->common_hal_data = sd_data;
|
||||||
// sd_data->len = max_packet_size;
|
// sd_data->len = max_packet_size;
|
||||||
|
@ -55,8 +55,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
|
|||||||
self->characteristic = characteristic;
|
self->characteristic = characteristic;
|
||||||
self->timeout_ms = timeout * 1000;
|
self->timeout_ms = timeout * 1000;
|
||||||
// This is a macro.
|
// This is a macro.
|
||||||
// true means long-lived, so it won't be moved.
|
ringbuf_alloc(&self->ringbuf, buffer_size);
|
||||||
ringbuf_alloc(&self->ringbuf, buffer_size, true);
|
|
||||||
|
|
||||||
bleio_characteristic_set_observer(characteristic, self);
|
bleio_characteristic_set_observer(characteristic, self);
|
||||||
}
|
}
|
||||||
|
@ -453,8 +453,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
|||||||
// for (size_t i = 0; i < response->count; ++i) {
|
// for (size_t i = 0; i < response->count; ++i) {
|
||||||
// ble_gattc_service_t *gattc_service = &response->services[i];
|
// ble_gattc_service_t *gattc_service = &response->services[i];
|
||||||
|
|
||||||
// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
|
// bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||||
// service->base.type = &bleio_service_type;
|
|
||||||
|
|
||||||
// // Initialize several fields at once.
|
// // Initialize several fields at once.
|
||||||
// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
|
// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
|
||||||
@ -466,8 +465,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
|||||||
|
|
||||||
// if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
// if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||||
// // Known service UUID.
|
// // Known service UUID.
|
||||||
// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
|
// bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
// uuid->base.type = &bleio_uuid_type;
|
|
||||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
|
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
|
||||||
// service->uuid = uuid;
|
// service->uuid = uuid;
|
||||||
// } else {
|
// } else {
|
||||||
@ -491,15 +489,14 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
|||||||
// for (size_t i = 0; i < response->count; ++i) {
|
// for (size_t i = 0; i < response->count; ++i) {
|
||||||
// ble_gattc_char_t *gattc_char = &response->chars[i];
|
// ble_gattc_char_t *gattc_char = &response->chars[i];
|
||||||
|
|
||||||
// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
|
// bleio_characteristic_obj_t *characteristic =
|
||||||
// characteristic->base.type = &bleio_characteristic_type;
|
// mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||||
|
|
||||||
// bleio_uuid_obj_t *uuid = NULL;
|
// bleio_uuid_obj_t *uuid = NULL;
|
||||||
|
|
||||||
// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||||
// // Known characteristic UUID.
|
// // Known characteristic UUID.
|
||||||
// uuid = m_new_obj(bleio_uuid_obj_t);
|
// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
// uuid->base.type = &bleio_uuid_type;
|
|
||||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
|
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
|
||||||
// } else {
|
// } else {
|
||||||
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
||||||
@ -557,15 +554,13 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
|||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
|
// bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
|
||||||
// descriptor->base.type = &bleio_descriptor_type;
|
|
||||||
|
|
||||||
// bleio_uuid_obj_t *uuid = NULL;
|
// bleio_uuid_obj_t *uuid = NULL;
|
||||||
|
|
||||||
// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||||
// // Known descriptor UUID.
|
// // Known descriptor UUID.
|
||||||
// uuid = m_new_obj(bleio_uuid_obj_t);
|
// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||||
// uuid->base.type = &bleio_uuid_type;
|
|
||||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
|
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
|
||||||
// } else {
|
// } else {
|
||||||
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
||||||
@ -750,8 +745,7 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *interna
|
|||||||
if (internal->connection_obj != mp_const_none) {
|
if (internal->connection_obj != mp_const_none) {
|
||||||
return internal->connection_obj;
|
return internal->connection_obj;
|
||||||
}
|
}
|
||||||
bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t);
|
bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type);
|
||||||
connection->base.type = &bleio_connection_type;
|
|
||||||
connection->connection = internal;
|
connection->connection = internal;
|
||||||
internal->connection_obj = connection;
|
internal->connection_obj = connection;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) {
|
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size))) {
|
||||||
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
|
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,8 +110,8 @@ void common_hal_bleio_packet_buffer_construct(
|
|||||||
self->packet_queued = false;
|
self->packet_queued = false;
|
||||||
self->pending_index = 0;
|
self->pending_index = 0;
|
||||||
self->pending_size = 0;
|
self->pending_size = 0;
|
||||||
self->outgoing[0] = m_malloc(max_packet_size, false);
|
self->outgoing[0] = m_malloc(max_packet_size);
|
||||||
self->outgoing[1] = m_malloc(max_packet_size, false);
|
self->outgoing[1] = m_malloc(max_packet_size);
|
||||||
} else {
|
} else {
|
||||||
self->outgoing[0] = NULL;
|
self->outgoing[0] = NULL;
|
||||||
self->outgoing[1] = NULL;
|
self->outgoing[1] = NULL;
|
||||||
|
@ -101,8 +101,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
|
|||||||
|
|
||||||
if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
|
if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
|
||||||
// We need a CCCD if this characteristic is doing notify or indicate.
|
// We need a CCCD if this characteristic is doing notify or indicate.
|
||||||
bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t);
|
bleio_descriptor_obj_t *cccd = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
|
||||||
cccd->base.type = &bleio_descriptor_type;
|
|
||||||
|
|
||||||
uint16_t zero = 0;
|
uint16_t zero = 0;
|
||||||
mp_buffer_info_t zero_cccd_value = {
|
mp_buffer_info_t zero_cccd_value = {
|
||||||
|
@ -19,6 +19,7 @@ Full Table of Contents
|
|||||||
:caption: API and Usage
|
:caption: API and Usage
|
||||||
|
|
||||||
../shared-bindings/index.rst
|
../shared-bindings/index.rst
|
||||||
|
library/index.rst
|
||||||
supported_ports.rst
|
supported_ports.rst
|
||||||
troubleshooting.rst
|
troubleshooting.rst
|
||||||
libraries.rst
|
libraries.rst
|
||||||
@ -32,13 +33,12 @@ Full Table of Contents
|
|||||||
design_guide
|
design_guide
|
||||||
porting
|
porting
|
||||||
common_hal
|
common_hal
|
||||||
|
reference/mpyfiles.rst
|
||||||
|
reference/glossary.rst
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: MicroPython specific
|
:caption: Python stand
|
||||||
|
|
||||||
library/index.rst
|
|
||||||
reference/glossary.rst
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`array` -- arrays of numeric data
|
:mod:`array` -- arrays of numeric data
|
||||||
=======================================
|
======================================
|
||||||
|
|
||||||
.. module:: array
|
.. module:: array
|
||||||
:synopsis: efficient arrays of numeric data
|
:synopsis: efficient arrays of numeric data
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:array`.
|
|see_cpython_module| :mod:`python:array`.
|
||||||
|
|
||||||
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
|
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
|
||||||
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`binascii` -- binary/ASCII conversions
|
:mod:`binascii` -- binary/ASCII conversions
|
||||||
============================================
|
===========================================
|
||||||
|
|
||||||
.. module:: binascii
|
.. module:: binascii
|
||||||
:synopsis: binary/ASCII conversions
|
:synopsis: binary/ASCII conversions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:binascii`.
|
|see_cpython_module| :mod:`python:binascii`.
|
||||||
|
|
||||||
This module implements conversions between binary data and various
|
This module implements conversions between binary data and various
|
||||||
encodings of it in ASCII form (in both directions).
|
encodings of it in ASCII form (in both directions).
|
||||||
@ -31,11 +31,11 @@ Functions
|
|||||||
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
|
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
|
||||||
Returns a bytes object.
|
Returns a bytes object.
|
||||||
|
|
||||||
.. function:: b2a_base64(data)
|
.. function:: b2a_base64(data, *, newline=True)
|
||||||
|
|
||||||
Encode binary data in base64 format, as in `RFC 3548
|
Encode binary data in base64 format, as in `RFC 3548
|
||||||
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
|
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
|
||||||
followed by a newline character, as a bytes object.
|
followed by a newline character if ``newline`` is true, as a bytes object.
|
||||||
|
|
||||||
.. function:: crc32(data, value=0, /)
|
.. function:: crc32(data, value=0, /)
|
||||||
|
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
:mod:`btree` -- simple BTree database
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: btree
|
|
||||||
:synopsis: simple BTree database
|
|
||||||
|
|
||||||
The ``btree`` module implements a simple key-value database using external
|
|
||||||
storage (disk files, or in general case, a random-access ``stream``). Keys are
|
|
||||||
stored sorted in the database, and besides efficient retrieval by a key
|
|
||||||
value, a database also supports efficient ordered range scans (retrieval
|
|
||||||
of values with the keys in a given range). On the application interface
|
|
||||||
side, BTree database work as close a possible to a way standard `dict`
|
|
||||||
type works, one notable difference is that both keys and values must
|
|
||||||
be `bytes` objects (so, if you want to store objects of other types, you
|
|
||||||
need to serialize them to `bytes` first).
|
|
||||||
|
|
||||||
The module is based on the well-known BerkelyDB library, version 1.xx.
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
import btree
|
|
||||||
|
|
||||||
# First, we need to open a stream which holds a database
|
|
||||||
# This is usually a file, but can be in-memory database
|
|
||||||
# using io.BytesIO, a raw flash partition, etc.
|
|
||||||
# Oftentimes, you want to create a database file if it doesn't
|
|
||||||
# exist and open if it exists. Idiom below takes care of this.
|
|
||||||
# DO NOT open database with "a+b" access mode.
|
|
||||||
try:
|
|
||||||
f = open("mydb", "r+b")
|
|
||||||
except OSError:
|
|
||||||
f = open("mydb", "w+b")
|
|
||||||
|
|
||||||
# Now open a database itself
|
|
||||||
db = btree.open(f)
|
|
||||||
|
|
||||||
# The keys you add will be sorted internally in the database
|
|
||||||
db[b"3"] = b"three"
|
|
||||||
db[b"1"] = b"one"
|
|
||||||
db[b"2"] = b"two"
|
|
||||||
|
|
||||||
# Assume that any changes are cached in memory unless
|
|
||||||
# explicitly flushed (or database closed). Flush database
|
|
||||||
# at the end of each "transaction".
|
|
||||||
db.flush()
|
|
||||||
|
|
||||||
# Prints b'two'
|
|
||||||
print(db[b"2"])
|
|
||||||
|
|
||||||
# Iterate over sorted keys in the database, starting from b"2"
|
|
||||||
# until the end of the database, returning only values.
|
|
||||||
# Mind that arguments passed to values() method are *key* values.
|
|
||||||
# Prints:
|
|
||||||
# b'two'
|
|
||||||
# b'three'
|
|
||||||
for word in db.values(b"2"):
|
|
||||||
print(word)
|
|
||||||
|
|
||||||
del db[b"2"]
|
|
||||||
|
|
||||||
# No longer true, prints False
|
|
||||||
print(b"2" in db)
|
|
||||||
|
|
||||||
# Prints:
|
|
||||||
# b"1"
|
|
||||||
# b"3"
|
|
||||||
for key in db:
|
|
||||||
print(key)
|
|
||||||
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
# Don't forget to close the underlying stream!
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
Functions
|
|
||||||
---------
|
|
||||||
|
|
||||||
.. function:: open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0)
|
|
||||||
|
|
||||||
Open a database from a random-access ``stream`` (like an open file). All
|
|
||||||
other parameters are optional and keyword-only, and allow to tweak advanced
|
|
||||||
parameters of the database operation (most users will not need them):
|
|
||||||
|
|
||||||
* *flags* - Currently unused.
|
|
||||||
* *pagesize* - Page size used for the nodes in BTree. Acceptable range
|
|
||||||
is 512-65536. If 0, a port-specific default will be used, optimized for
|
|
||||||
port's memory usage and/or performance.
|
|
||||||
* *cachesize* - Suggested memory cache size in bytes. For a
|
|
||||||
board with enough memory using larger values may improve performance.
|
|
||||||
Cache policy is as follows: entire cache is not allocated at once;
|
|
||||||
instead, accessing a new page in database will allocate a memory buffer
|
|
||||||
for it, until value specified by *cachesize* is reached. Then, these
|
|
||||||
buffers will be managed using LRU (least recently used) policy. More
|
|
||||||
buffers may still be allocated if needed (e.g., if a database contains
|
|
||||||
big keys and/or values). Allocated cache buffers aren't reclaimed.
|
|
||||||
* *minkeypage* - Minimum number of keys to store per page. Default value
|
|
||||||
of 0 equivalent to 2.
|
|
||||||
|
|
||||||
Returns a BTree object, which implements a dictionary protocol (set
|
|
||||||
of methods), and some additional methods described below.
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. method:: btree.close()
|
|
||||||
|
|
||||||
Close the database. It's mandatory to close the database at the end of
|
|
||||||
processing, as some unwritten data may be still in the cache. Note that
|
|
||||||
this does not close underlying stream with which the database was opened,
|
|
||||||
it should be closed separately (which is also mandatory to make sure that
|
|
||||||
data flushed from buffer to the underlying storage).
|
|
||||||
|
|
||||||
.. method:: btree.flush()
|
|
||||||
|
|
||||||
Flush any data in cache to the underlying stream.
|
|
||||||
|
|
||||||
.. method:: btree.__getitem__(key)
|
|
||||||
btree.get(key, default=None, /)
|
|
||||||
btree.__setitem__(key, val)
|
|
||||||
btree.__delitem__(key)
|
|
||||||
btree.__contains__(key)
|
|
||||||
|
|
||||||
Standard dictionary methods.
|
|
||||||
|
|
||||||
.. method:: btree.__iter__()
|
|
||||||
|
|
||||||
A BTree object can be iterated over directly (similar to a dictionary)
|
|
||||||
to get access to all keys in order.
|
|
||||||
|
|
||||||
.. method:: btree.keys([start_key, [end_key, [flags]]])
|
|
||||||
btree.values([start_key, [end_key, [flags]]])
|
|
||||||
btree.items([start_key, [end_key, [flags]]])
|
|
||||||
|
|
||||||
These methods are similar to standard dictionary methods, but also can
|
|
||||||
take optional parameters to iterate over a key sub-range, instead of
|
|
||||||
the entire database. Note that for all 3 methods, *start_key* and
|
|
||||||
*end_key* arguments represent key values. For example, `values()`
|
|
||||||
method will iterate over values corresponding to they key range
|
|
||||||
given. None values for *start_key* means "from the first key", no
|
|
||||||
*end_key* or its value of None means "until the end of database".
|
|
||||||
By default, range is inclusive of *start_key* and exclusive of
|
|
||||||
*end_key*, you can include *end_key* in iteration by passing *flags*
|
|
||||||
of `btree.INCL`. You can iterate in descending key direction
|
|
||||||
by passing *flags* of `btree.DESC`. The flags values can be ORed
|
|
||||||
together.
|
|
||||||
|
|
||||||
Constants
|
|
||||||
---------
|
|
||||||
|
|
||||||
.. data:: INCL
|
|
||||||
|
|
||||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
|
||||||
scanning should be inclusive of the end key.
|
|
||||||
|
|
||||||
.. data:: DESC
|
|
||||||
|
|
||||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
|
||||||
scanning should be in descending direction of keys.
|
|
@ -33,7 +33,7 @@ Functions and types
|
|||||||
|
|
||||||
.. class:: bytes()
|
.. class:: bytes()
|
||||||
|
|
||||||
|see_cpython| `bytes`.
|
|see_cpython| `python:bytes`.
|
||||||
|
|
||||||
.. function:: callable()
|
.. function:: callable()
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ Functions and types
|
|||||||
|
|
||||||
.. class:: frozenset()
|
.. class:: frozenset()
|
||||||
|
|
||||||
`frozenset()` is not enabled on non-Express CircuitPython boards.
|
`frozenset()` is not enabled on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. function:: getattr()
|
.. function:: getattr()
|
||||||
|
|
||||||
@ -88,12 +88,12 @@ Functions and types
|
|||||||
|
|
||||||
.. classmethod:: from_bytes(bytes, byteorder)
|
.. classmethod:: from_bytes(bytes, byteorder)
|
||||||
|
|
||||||
In CircuitPython, ``byteorder`` parameter must be positional (this is
|
In CircuitPython, the ``byteorder`` parameter must be positional (this is
|
||||||
compatible with CPython).
|
compatible with CPython).
|
||||||
|
|
||||||
.. method:: to_bytes(size, byteorder)
|
.. method:: to_bytes(size, byteorder)
|
||||||
|
|
||||||
In CircuitPython, ``byteorder`` parameter must be positional (this is
|
In CircuitPython, the ``byteorder`` parameter must be positional (this is
|
||||||
compatible with CPython).
|
compatible with CPython).
|
||||||
|
|
||||||
.. function:: isinstance()
|
.. function:: isinstance()
|
||||||
@ -138,7 +138,7 @@ Functions and types
|
|||||||
|
|
||||||
.. function:: reversed()
|
.. function:: reversed()
|
||||||
|
|
||||||
`reversed()` is not enabled on non-Express CircuitPython boards.
|
`reversed()` is not enabled on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. function:: round()
|
.. function:: round()
|
||||||
|
|
||||||
@ -224,10 +224,14 @@ Exceptions
|
|||||||
|
|
||||||
.. exception:: SystemExit
|
.. exception:: SystemExit
|
||||||
|
|
||||||
|
|see_cpython| `python:SystemExit`.
|
||||||
|
|
||||||
.. exception:: TimeoutError
|
.. exception:: TimeoutError
|
||||||
|
|
||||||
.. exception:: TypeError
|
.. exception:: TypeError
|
||||||
|
|
||||||
|
|see_cpython| `python:TypeError`.
|
||||||
|
|
||||||
.. exception:: UnicodeError
|
.. exception:: UnicodeError
|
||||||
|
|
||||||
.. exception:: ValueError
|
.. exception:: ValueError
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
:mod:`collections` -- collection and container types
|
:mod:`collections` -- collection and container types
|
||||||
=====================================================
|
====================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
**Limitations:** Not implemented on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. module:: collections
|
.. module:: collections
|
||||||
:synopsis: collection and container types
|
:synopsis: collection and container types
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:collections`.
|
|see_cpython_module| :mod:`python:collections`.
|
||||||
|
|
||||||
This module implements advanced collection and container types to
|
This module implements advanced collection and container types to
|
||||||
hold/accumulate various objects.
|
hold/accumulate various objects.
|
||||||
@ -14,7 +14,7 @@ hold/accumulate various objects.
|
|||||||
Classes
|
Classes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. function:: deque(iterable, maxlen[, flags])
|
.. class:: deque(iterable, maxlen[, flags])
|
||||||
|
|
||||||
Deques (double-ended queues) are a list-like container that support O(1)
|
Deques (double-ended queues) are a list-like container that support O(1)
|
||||||
appends and pops from either side of the deque. New deques are created
|
appends and pops from either side of the deque. New deques are created
|
||||||
@ -59,7 +59,7 @@ Classes
|
|||||||
print(t1.name)
|
print(t1.name)
|
||||||
assert t2.name == t2[1]
|
assert t2.name == t2[1]
|
||||||
|
|
||||||
.. function:: OrderedDict(...)
|
.. class:: OrderedDict(...)
|
||||||
|
|
||||||
``dict`` type subclass which remembers and preserves the order of keys
|
``dict`` type subclass which remembers and preserves the order of keys
|
||||||
added. When ordered dict is iterated over, keys/items are returned in
|
added. When ordered dict is iterated over, keys/items are returned in
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
.. module:: errno
|
.. module:: errno
|
||||||
:synopsis: system error codes
|
:synopsis: system error codes
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:errno`.
|
|see_cpython_module| :mod:`python:errno`.
|
||||||
|
|
||||||
This module provides access to symbolic error codes for `OSError` exception.
|
This module provides access to symbolic error codes for `OSError` exception.
|
||||||
A particular inventory of codes depends on :term:`MicroPython port`.
|
The codes available may vary per CircuitPython build.
|
||||||
|
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
@ -15,14 +15,13 @@ Constants
|
|||||||
.. data:: EEXIST, EAGAIN, etc.
|
.. data:: EEXIST, EAGAIN, etc.
|
||||||
|
|
||||||
Error codes, based on ANSI C/POSIX standard. All error codes start with
|
Error codes, based on ANSI C/POSIX standard. All error codes start with
|
||||||
"E". As mentioned above, inventory of the codes depends on
|
"E". Errors are usually accessible as ``exc.errno``
|
||||||
:term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]``
|
|
||||||
where ``exc`` is an instance of `OSError`. Usage example::
|
where ``exc`` is an instance of `OSError`. Usage example::
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.mkdir("my_dir")
|
os.mkdir("my_dir")
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
if exc.args[0] == errno.EEXIST:
|
if exc.errno == errno.EEXIST:
|
||||||
print("Directory already exists")
|
print("Directory already exists")
|
||||||
|
|
||||||
.. data:: errorcode
|
.. data:: errorcode
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
:mod:`framebuf` --- frame buffer manipulation
|
|
||||||
=============================================
|
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: framebuf
|
|
||||||
:synopsis: Frame buffer manipulation
|
|
||||||
|
|
||||||
This module provides a general frame buffer which can be used to create
|
|
||||||
bitmap images, which can then be sent to a display.
|
|
||||||
|
|
||||||
class FrameBuffer
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The FrameBuffer class provides a pixel buffer which can be drawn upon with
|
|
||||||
pixels, lines, rectangles, text and even other FrameBuffer's. It is useful
|
|
||||||
when generating output for displays.
|
|
||||||
|
|
||||||
For example::
|
|
||||||
|
|
||||||
import framebuf
|
|
||||||
|
|
||||||
# FrameBuffer needs 2 bytes for every RGB565 pixel
|
|
||||||
fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)
|
|
||||||
|
|
||||||
fbuf.fill(0)
|
|
||||||
fbuf.text('MicroPython!', 0, 0, 0xffff)
|
|
||||||
fbuf.hline(0, 9, 96, 0xffff)
|
|
||||||
|
|
||||||
Constructors
|
|
||||||
------------
|
|
||||||
|
|
||||||
.. class:: FrameBuffer(buffer, width, height, format, stride=width, /)
|
|
||||||
|
|
||||||
Construct a FrameBuffer object. The parameters are:
|
|
||||||
|
|
||||||
- *buffer* is an object with a buffer protocol which must be large
|
|
||||||
enough to contain every pixel defined by the width, height and
|
|
||||||
format of the FrameBuffer.
|
|
||||||
- *width* is the width of the FrameBuffer in pixels
|
|
||||||
- *height* is the height of the FrameBuffer in pixels
|
|
||||||
- *format* specifies the type of pixel used in the FrameBuffer;
|
|
||||||
permissible values are listed under Constants below. These set the
|
|
||||||
number of bits used to encode a color value and the layout of these
|
|
||||||
bits in *buffer*.
|
|
||||||
Where a color value c is passed to a method, c is a small integer
|
|
||||||
with an encoding that is dependent on the format of the FrameBuffer.
|
|
||||||
- *stride* is the number of pixels between each horizontal line
|
|
||||||
of pixels in the FrameBuffer. This defaults to *width* but may
|
|
||||||
need adjustments when implementing a FrameBuffer within another
|
|
||||||
larger FrameBuffer or screen. The *buffer* size must accommodate
|
|
||||||
an increased step size.
|
|
||||||
|
|
||||||
One must specify valid *buffer*, *width*, *height*, *format* and
|
|
||||||
optionally *stride*. Invalid *buffer* size or dimensions may lead to
|
|
||||||
unexpected errors.
|
|
||||||
|
|
||||||
Drawing primitive shapes
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The following methods draw shapes onto the FrameBuffer.
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.fill(c)
|
|
||||||
|
|
||||||
Fill the entire FrameBuffer with the specified color.
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.pixel(x, y[, c])
|
|
||||||
|
|
||||||
If *c* is not given, get the color value of the specified pixel.
|
|
||||||
If *c* is given, set the specified pixel to the given color.
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.hline(x, y, w, c)
|
|
||||||
.. method:: FrameBuffer.vline(x, y, h, c)
|
|
||||||
.. method:: FrameBuffer.line(x1, y1, x2, y2, c)
|
|
||||||
|
|
||||||
Draw a line from a set of coordinates using the given color and
|
|
||||||
a thickness of 1 pixel. The `line` method draws the line up to
|
|
||||||
a second set of coordinates whereas the `hline` and `vline`
|
|
||||||
methods draw horizontal and vertical lines respectively up to
|
|
||||||
a given length.
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.rect(x, y, w, h, c)
|
|
||||||
.. method:: FrameBuffer.fill_rect(x, y, w, h, c)
|
|
||||||
|
|
||||||
Draw a rectangle at the given location, size and color. The `rect`
|
|
||||||
method draws only a 1 pixel outline whereas the `fill_rect` method
|
|
||||||
draws both the outline and interior.
|
|
||||||
|
|
||||||
Drawing text
|
|
||||||
------------
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.text(s, x, y[, c])
|
|
||||||
|
|
||||||
Write text to the FrameBuffer using the the coordinates as the upper-left
|
|
||||||
corner of the text. The color of the text can be defined by the optional
|
|
||||||
argument but is otherwise a default value of 1. All characters have
|
|
||||||
dimensions of 8x8 pixels and there is currently no way to change the font.
|
|
||||||
|
|
||||||
|
|
||||||
Other methods
|
|
||||||
-------------
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.scroll(xstep, ystep)
|
|
||||||
|
|
||||||
Shift the contents of the FrameBuffer by the given vector. This may
|
|
||||||
leave a footprint of the previous colors in the FrameBuffer.
|
|
||||||
|
|
||||||
.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None)
|
|
||||||
|
|
||||||
Draw another FrameBuffer on top of the current one at the given coordinates.
|
|
||||||
If *key* is specified then it should be a color integer and the
|
|
||||||
corresponding color will be considered transparent: all pixels with that
|
|
||||||
color value will not be drawn.
|
|
||||||
|
|
||||||
The *palette* argument enables blitting between FrameBuffers with differing
|
|
||||||
formats. Typical usage is to render a monochrome or grayscale glyph/icon to
|
|
||||||
a color display. The *palette* is a FrameBuffer instance whose format is
|
|
||||||
that of the current FrameBuffer. The *palette* height is one pixel and its
|
|
||||||
pixel width is the number of colors in the source FrameBuffer. The *palette*
|
|
||||||
for an N-bit source needs 2**N pixels; the *palette* for a monochrome source
|
|
||||||
would have 2 pixels representing background and foreground colors. The
|
|
||||||
application assigns a color to each pixel in the *palette*. The color of the
|
|
||||||
current pixel will be that of that *palette* pixel whose x position is the
|
|
||||||
color of the corresponding source pixel.
|
|
||||||
|
|
||||||
Constants
|
|
||||||
---------
|
|
||||||
|
|
||||||
.. data:: framebuf.MONO_VLSB
|
|
||||||
|
|
||||||
Monochrome (1-bit) color format
|
|
||||||
This defines a mapping where the bits in a byte are vertically mapped with
|
|
||||||
bit 0 being nearest the top of the screen. Consequently each byte occupies
|
|
||||||
8 vertical pixels. Subsequent bytes appear at successive horizontal
|
|
||||||
locations until the rightmost edge is reached. Further bytes are rendered
|
|
||||||
at locations starting at the leftmost edge, 8 pixels lower.
|
|
||||||
|
|
||||||
.. data:: framebuf.MONO_HLSB
|
|
||||||
|
|
||||||
Monochrome (1-bit) color format
|
|
||||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
|
||||||
Each byte occupies 8 horizontal pixels with bit 7 being the leftmost.
|
|
||||||
Subsequent bytes appear at successive horizontal locations until the
|
|
||||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
|
||||||
pixel lower.
|
|
||||||
|
|
||||||
.. data:: framebuf.MONO_HMSB
|
|
||||||
|
|
||||||
Monochrome (1-bit) color format
|
|
||||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
|
||||||
Each byte occupies 8 horizontal pixels with bit 0 being the leftmost.
|
|
||||||
Subsequent bytes appear at successive horizontal locations until the
|
|
||||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
|
||||||
pixel lower.
|
|
||||||
|
|
||||||
.. data:: framebuf.RGB565
|
|
||||||
|
|
||||||
Red Green Blue (16-bit, 5+6+5) color format
|
|
||||||
|
|
||||||
.. data:: framebuf.GS2_HMSB
|
|
||||||
|
|
||||||
Grayscale (2-bit) color format
|
|
||||||
|
|
||||||
.. data:: framebuf.GS4_HMSB
|
|
||||||
|
|
||||||
Grayscale (4-bit) color format
|
|
||||||
|
|
||||||
.. data:: framebuf.GS8
|
|
||||||
|
|
||||||
Grayscale (8-bit) color format
|
|
@ -1,12 +1,10 @@
|
|||||||
:mod:`gc` -- control the garbage collector
|
:mod:`gc` -- control the garbage collector
|
||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: gc
|
.. module:: gc
|
||||||
:synopsis: control the garbage collector
|
:synopsis: control the garbage collector
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:gc`.
|
|see_cpython_module| :mod:`python:gc`.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
@ -63,6 +61,6 @@ Functions
|
|||||||
.. admonition:: Difference to CPython
|
.. admonition:: Difference to CPython
|
||||||
:class: attention
|
:class: attention
|
||||||
|
|
||||||
This function is a a MicroPython extension. CPython has a similar
|
This function is a MicroPython extension. CPython has a similar
|
||||||
function - ``set_threshold()``, but due to different GC
|
function - ``set_threshold()``, but due to different GC
|
||||||
implementations, its signature and semantics are different.
|
implementations, its signature and semantics are different.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
.. module:: heapq
|
.. module:: heapq
|
||||||
:synopsis: heap queue algorithm
|
:synopsis: heap queue algorithm
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:heapq`.
|
|see_cpython_module| :mod:`python:heapq`.
|
||||||
|
|
||||||
This module implements the
|
This module implements the
|
||||||
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
|
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
.. _micropython_lib:
|
.. _micropython_lib:
|
||||||
|
|
||||||
MicroPython libraries
|
Standard Libraries
|
||||||
=====================
|
==================
|
||||||
|
|
||||||
Python standard libraries and micro-libraries
|
Python standard libraries
|
||||||
---------------------------------------------
|
-------------------------
|
||||||
|
|
||||||
The libraries below are inherited from MicroPython.
|
The libraries below implement a subset of the corresponding
|
||||||
They are similar to the standard Python libraries with the same name.
|
standard Python (CPython) library. They are implemented in C, not Python.
|
||||||
They implement a subset of or a variant of the corresponding
|
|
||||||
standard Python library.
|
|
||||||
|
|
||||||
CircuitPython's long-term goal is that code written in CircuitPython
|
CircuitPython's long-term goal is that code written in CircuitPython
|
||||||
using Python standard libraries will be runnable on CPython without changes.
|
using Python standard libraries will be runnable on CPython without changes.
|
||||||
|
|
||||||
These libraries are not enabled on CircuitPython builds with
|
These libraries are not enabled on CircuitPython builds with
|
||||||
limited flash memory, usually on non-Express builds:
|
limited flash memory:
|
||||||
``binascii``, ``errno``, ``json``, ``re``.
|
``binascii``, ``errno``, ``json``, ``re``.
|
||||||
|
|
||||||
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
||||||
@ -38,11 +36,11 @@ These libraries are not currently enabled in any CircuitPython build, but may be
|
|||||||
ctypes.rst
|
ctypes.rst
|
||||||
select.rst
|
select.rst
|
||||||
|
|
||||||
Omitted functions in the ``string`` library
|
Omitted ``string`` functions
|
||||||
-------------------------------------------
|
----------------------------
|
||||||
|
|
||||||
A few string operations are not enabled on small builds
|
A few string operations are not enabled on small builds
|
||||||
(usually non-Express), due to limited flash memory:
|
due to limited flash memory:
|
||||||
``string.center()``, ``string.partition()``, ``string.splitlines()``,
|
``string.center()``, ``string.partition()``, ``string.splitlines()``,
|
||||||
``string.reversed()``.
|
``string.reversed()``.
|
||||||
|
|
||||||
@ -50,13 +48,10 @@ A few string operations are not enabled on small builds
|
|||||||
CircuitPython/MicroPython-specific libraries
|
CircuitPython/MicroPython-specific libraries
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
Functionality specific to the CircuitPython/MicroPython implementation is available in
|
Functionality specific to the CircuitPython/MicroPython implementations is available in
|
||||||
the following libraries. These libraries may change significantly or be removed in future
|
the following libraries.
|
||||||
versions of CircuitPython.
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
btree.rst
|
|
||||||
framebuf.rst
|
|
||||||
micropython.rst
|
micropython.rst
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`io` -- input/output streams
|
:mod:`io` -- input/output streams
|
||||||
==================================
|
=================================
|
||||||
|
|
||||||
.. module:: io
|
.. module:: io
|
||||||
:synopsis: input/output streams
|
:synopsis: input/output streams
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:io`.
|
|see_cpython_module| :mod:`python:io`.
|
||||||
|
|
||||||
This module contains additional types of ``stream`` (file-like) objects
|
This module contains additional types of ``stream`` (file-like) objects
|
||||||
and helper functions.
|
and helper functions.
|
||||||
@ -112,3 +112,20 @@ Classes
|
|||||||
.. method:: getvalue()
|
.. method:: getvalue()
|
||||||
|
|
||||||
Get the current contents of the underlying buffer which holds data.
|
Get the current contents of the underlying buffer which holds data.
|
||||||
|
|
||||||
|
.. class:: StringIO(alloc_size)
|
||||||
|
:noindex:
|
||||||
|
.. class:: BytesIO(alloc_size)
|
||||||
|
:noindex:
|
||||||
|
|
||||||
|
Create an empty `StringIO`/`BytesIO` object, preallocated to hold up
|
||||||
|
to *alloc_size* number of bytes. That means that writing that amount
|
||||||
|
of bytes won't lead to reallocation of the buffer, and thus won't hit
|
||||||
|
out-of-memory situation or lead to memory fragmentation. These constructors
|
||||||
|
are a MicroPython extension and are recommended for usage only in special
|
||||||
|
cases and in system-level libraries, not for end-user applications.
|
||||||
|
|
||||||
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
These constructors are a MicroPython extension.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`json` -- JSON encoding and decoding
|
:mod:`json` -- JSON encoding and decoding
|
||||||
==========================================
|
=========================================
|
||||||
|
|
||||||
.. module:: json
|
.. module:: json
|
||||||
:synopsis: JSON encoding and decoding
|
:synopsis: JSON encoding and decoding
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:json`.
|
|see_cpython_module| :mod:`python:json`.
|
||||||
|
|
||||||
This modules allows to convert between Python objects and the JSON
|
This modules allows to convert between Python objects and the JSON
|
||||||
data format.
|
data format.
|
||||||
@ -12,14 +12,20 @@ data format.
|
|||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
|
|
||||||
.. function:: dump(obj, stream)
|
.. function:: dump(obj, stream, separators=None)
|
||||||
|
|
||||||
Serialise ``obj`` to a JSON string, writing it to the given *stream*.
|
Serialise ``obj`` to a JSON string, writing it to the given *stream*.
|
||||||
|
|
||||||
.. function:: dumps(obj)
|
If specified, separators should be an ``(item_separator, key_separator)``
|
||||||
|
tuple. The default is ``(', ', ': ')``. To get the most compact JSON
|
||||||
|
representation, you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
|
||||||
|
.. function:: dumps(obj, separators=None)
|
||||||
|
|
||||||
Return ``obj`` represented as a JSON string.
|
Return ``obj`` represented as a JSON string.
|
||||||
|
|
||||||
|
The arguments have the same meaning as in `dump`.
|
||||||
|
|
||||||
.. function:: load(stream)
|
.. function:: load(stream)
|
||||||
|
|
||||||
Parse the given ``stream``, interpreting it as a JSON string and
|
Parse the given ``stream``, interpreting it as a JSON string and
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
:mod:`micropython` -- access and control MicroPython internals
|
:mod:`micropython` -- MicroPython extensions and internals
|
||||||
==============================================================
|
==========================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: micropython
|
.. module:: micropython
|
||||||
:synopsis: access and control MicroPython internals
|
:synopsis: access and control MicroPython internals
|
||||||
@ -11,7 +9,7 @@ Functions
|
|||||||
|
|
||||||
.. function:: const(expr)
|
.. function:: const(expr)
|
||||||
|
|
||||||
Used to declare that the expression is a constant so that the compile can
|
Used to declare that the expression is a constant so that the compiler can
|
||||||
optimise it. The use of this function should be as follows::
|
optimise it. The use of this function should be as follows::
|
||||||
|
|
||||||
from micropython import const
|
from micropython import const
|
||||||
@ -28,111 +26,3 @@ Functions
|
|||||||
provided as part of the :mod:`micropython` module mainly so that scripts can be
|
provided as part of the :mod:`micropython` module mainly so that scripts can be
|
||||||
written which run under both CPython and MicroPython, by following the above
|
written which run under both CPython and MicroPython, by following the above
|
||||||
pattern.
|
pattern.
|
||||||
|
|
||||||
.. function:: opt_level([level])
|
|
||||||
|
|
||||||
If *level* is given then this function sets the optimisation level for subsequent
|
|
||||||
compilation of scripts, and returns ``None``. Otherwise it returns the current
|
|
||||||
optimisation level.
|
|
||||||
|
|
||||||
The optimisation level controls the following compilation features:
|
|
||||||
|
|
||||||
- Assertions: at level 0 assertion statements are enabled and compiled into the
|
|
||||||
bytecode; at levels 1 and higher assertions are not compiled.
|
|
||||||
- Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``;
|
|
||||||
at levels 1 and higher it expands to ``False``.
|
|
||||||
- Source-code line numbers: at levels 0, 1 and 2 source-code line number are
|
|
||||||
stored along with the bytecode so that exceptions can report the line number
|
|
||||||
they occurred at; at levels 3 and higher line numbers are not stored.
|
|
||||||
|
|
||||||
The default optimisation level is usually level 0.
|
|
||||||
|
|
||||||
.. function:: mem_info([verbose])
|
|
||||||
|
|
||||||
Print information about currently used memory. If the *verbose* argument
|
|
||||||
is given then extra information is printed.
|
|
||||||
|
|
||||||
The information that is printed is implementation dependent, but currently
|
|
||||||
includes the amount of stack and heap used. In verbose mode it prints out
|
|
||||||
the entire heap indicating which blocks are used and which are free.
|
|
||||||
|
|
||||||
.. function:: qstr_info([verbose])
|
|
||||||
|
|
||||||
Print information about currently interned strings. If the *verbose*
|
|
||||||
argument is given then extra information is printed.
|
|
||||||
|
|
||||||
The information that is printed is implementation dependent, but currently
|
|
||||||
includes the number of interned strings and the amount of RAM they use. In
|
|
||||||
verbose mode it prints out the names of all RAM-interned strings.
|
|
||||||
|
|
||||||
.. function:: stack_use()
|
|
||||||
|
|
||||||
Return an integer representing the current amount of stack that is being
|
|
||||||
used. The absolute value of this is not particularly useful, rather it
|
|
||||||
should be used to compute differences in stack usage at different points.
|
|
||||||
|
|
||||||
.. function:: heap_lock()
|
|
||||||
.. function:: heap_unlock()
|
|
||||||
.. function:: heap_locked()
|
|
||||||
|
|
||||||
Lock or unlock the heap. When locked no memory allocation can occur and a
|
|
||||||
``MemoryError`` will be raised if any heap allocation is attempted.
|
|
||||||
`heap_locked()` returns a true value if the heap is currently locked.
|
|
||||||
|
|
||||||
These functions can be nested, ie `heap_lock()` can be called multiple times
|
|
||||||
in a row and the lock-depth will increase, and then `heap_unlock()` must be
|
|
||||||
called the same number of times to make the heap available again.
|
|
||||||
|
|
||||||
Both `heap_unlock()` and `heap_locked()` return the current lock depth
|
|
||||||
(after unlocking for the former) as a non-negative integer, with 0 meaning
|
|
||||||
the heap is not locked.
|
|
||||||
|
|
||||||
If the REPL becomes active with the heap locked then it will be forcefully
|
|
||||||
unlocked.
|
|
||||||
|
|
||||||
Note: `heap_locked()` is not enabled on most ports by default,
|
|
||||||
requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``.
|
|
||||||
|
|
||||||
.. function:: kbd_intr(chr)
|
|
||||||
|
|
||||||
Set the character that will raise a `KeyboardInterrupt` exception. By
|
|
||||||
default this is set to 3 during script execution, corresponding to Ctrl-C.
|
|
||||||
Passing -1 to this function will disable capture of Ctrl-C, and passing 3
|
|
||||||
will restore it.
|
|
||||||
|
|
||||||
This function can be used to prevent the capturing of Ctrl-C on the
|
|
||||||
incoming stream of characters that is usually used for the REPL, in case
|
|
||||||
that stream is used for other purposes.
|
|
||||||
|
|
||||||
.. function:: schedule(func, arg)
|
|
||||||
|
|
||||||
Schedule the function *func* to be executed "very soon". The function
|
|
||||||
is passed the value *arg* as its single argument. "Very soon" means that
|
|
||||||
the MicroPython runtime will do its best to execute the function at the
|
|
||||||
earliest possible time, given that it is also trying to be efficient, and
|
|
||||||
that the following conditions hold:
|
|
||||||
|
|
||||||
- A scheduled function will never preempt another scheduled function.
|
|
||||||
- Scheduled functions are always executed "between opcodes" which means
|
|
||||||
that all fundamental Python operations (such as appending to a list)
|
|
||||||
are guaranteed to be atomic.
|
|
||||||
- A given port may define "critical regions" within which scheduled
|
|
||||||
functions will never be executed. Functions may be scheduled within
|
|
||||||
a critical region but they will not be executed until that region
|
|
||||||
is exited. An example of a critical region is a preempting interrupt
|
|
||||||
handler (an IRQ).
|
|
||||||
|
|
||||||
A use for this function is to schedule a callback from a preempting IRQ.
|
|
||||||
Such an IRQ puts restrictions on the code that runs in the IRQ (for example
|
|
||||||
the heap may be locked) and scheduling a function to call later will lift
|
|
||||||
those restrictions.
|
|
||||||
|
|
||||||
Note: If `schedule()` is called from a preempting IRQ, when memory
|
|
||||||
allocation is not allowed and the callback to be passed to `schedule()` is
|
|
||||||
a bound method, passing this directly will fail. This is because creating a
|
|
||||||
reference to a bound method causes memory allocation. A solution is to
|
|
||||||
create a reference to the method in the class constructor and to pass that
|
|
||||||
reference to `schedule()`.
|
|
||||||
|
|
||||||
There is a finite queue to hold the scheduled functions and `schedule()`
|
|
||||||
will raise a `RuntimeError` if the queue is full.
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`re` -- simple regular expressions
|
:mod:`re` -- simple regular expressions
|
||||||
========================================
|
=======================================
|
||||||
|
|
||||||
.. module:: re
|
.. module:: re
|
||||||
:synopsis: regular expressions
|
:synopsis: regular expressions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:re`.
|
|see_cpython_module| :mod:`python:re`.
|
||||||
|
|
||||||
This module implements regular expression operations. Regular expression
|
This module implements regular expression operations. Regular expression
|
||||||
syntax supported is a subset of CPython ``re`` module (and actually is
|
syntax supported is a subset of CPython ``re`` module (and actually is
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
:mod:`select` -- wait for events on a set of streams
|
:mod:`select` -- wait for events on a set of streams
|
||||||
====================================================
|
====================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: select
|
.. module:: select
|
||||||
:synopsis: wait for events on a set of streams
|
:synopsis: wait for events on a set of streams
|
||||||
|
|
||||||
@ -86,7 +84,7 @@ Methods
|
|||||||
.. method:: poll.ipoll(timeout=-1, flags=0, /)
|
.. method:: poll.ipoll(timeout=-1, flags=0, /)
|
||||||
|
|
||||||
Like :meth:`poll.poll`, but instead returns an iterator which yields a
|
Like :meth:`poll.poll`, but instead returns an iterator which yields a
|
||||||
``callee-owned tuples``. This function provides efficient, allocation-free
|
"callee-owned tuple". This function provides an efficient, allocation-free
|
||||||
way to poll on streams.
|
way to poll on streams.
|
||||||
|
|
||||||
If *flags* is 1, one-shot behaviour for events is employed: streams for
|
If *flags* is 1, one-shot behaviour for events is employed: streams for
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
:mod:`sys` -- system specific functions
|
:mod:`sys` -- system specific functions
|
||||||
========================================
|
=======================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: sys
|
.. module:: sys
|
||||||
:synopsis: system specific functions
|
:synopsis: system specific functions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:sys`.
|
|see_cpython_module| :mod:`python:sys`.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
@ -35,6 +33,7 @@ Constants
|
|||||||
|
|
||||||
* *name* - string "circuitpython"
|
* *name* - string "circuitpython"
|
||||||
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
|
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
|
||||||
|
* *_mpy* - supported mpy file-format version (optional attribute)
|
||||||
|
|
||||||
This object is the recommended way to distinguish CircuitPython from other
|
This object is the recommended way to distinguish CircuitPython from other
|
||||||
Python implementations (note that it still may not exist in the very
|
Python implementations (note that it still may not exist in the very
|
||||||
@ -97,6 +96,12 @@ Constants
|
|||||||
If you need to check whether your program runs on CircuitPython (vs other
|
If you need to check whether your program runs on CircuitPython (vs other
|
||||||
Python implementation), use `sys.implementation` instead.
|
Python implementation), use `sys.implementation` instead.
|
||||||
|
|
||||||
|
.. data:: ps1
|
||||||
|
ps2
|
||||||
|
|
||||||
|
Mutable attributes holding strings, which are used for the REPL prompt. The defaults
|
||||||
|
give the standard Python prompt of ``>>>`` and ``...``.
|
||||||
|
|
||||||
.. data:: stderr
|
.. data:: stderr
|
||||||
|
|
||||||
Standard error ``stream``.
|
Standard error ``stream``.
|
||||||
@ -109,6 +114,14 @@ Constants
|
|||||||
|
|
||||||
Standard output ``stream``.
|
Standard output ``stream``.
|
||||||
|
|
||||||
|
.. data:: tracebacklimit
|
||||||
|
|
||||||
|
A mutable attribute holding an integer value which is the maximum number of traceback
|
||||||
|
entries to store in an exception. Set to 0 to disable adding tracebacks. Defaults
|
||||||
|
to 1000.
|
||||||
|
|
||||||
|
Note: this is not available on all ports.
|
||||||
|
|
||||||
.. data:: version
|
.. data:: version
|
||||||
|
|
||||||
Python language version that this implementation conforms to, as a string.
|
Python language version that this implementation conforms to, as a string.
|
||||||
|
@ -159,7 +159,7 @@ Glossary
|
|||||||
typically accessible on a host PC via USB.
|
typically accessible on a host PC via USB.
|
||||||
|
|
||||||
stream
|
stream
|
||||||
Also known as a "file-like object". An Python object which provides
|
Also known as a "file-like object". A Python object which provides
|
||||||
sequential read-write access to the underlying data. A stream object
|
sequential read-write access to the underlying data. A stream object
|
||||||
implements a corresponding interface, which consists of methods like
|
implements a corresponding interface, which consists of methods like
|
||||||
``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``,
|
``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``,
|
||||||
|
199
docs/reference/mpyfiles.rst
Normal file
199
docs/reference/mpyfiles.rst
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
.. _mpy_files:
|
||||||
|
|
||||||
|
MicroPython .mpy files
|
||||||
|
======================
|
||||||
|
|
||||||
|
MicroPython defines the concept of an .mpy file which is a binary container
|
||||||
|
file format that holds precompiled code, and which can be imported like a
|
||||||
|
normal .py module. The file ``foo.mpy`` can be imported via ``import foo``,
|
||||||
|
as long as ``foo.mpy`` can be found in the usual way by the import machinery.
|
||||||
|
Usually, each directory listed in ``sys.path`` is searched in order. When
|
||||||
|
searching a particular directory ``foo.py`` is looked for first and if that
|
||||||
|
is not found then ``foo.mpy`` is looked for, then the search continues in the
|
||||||
|
next directory if neither is found. As such, ``foo.py`` will take precedence
|
||||||
|
over ``foo.mpy``.
|
||||||
|
|
||||||
|
These .mpy files can contain bytecode which is usually generated from Python
|
||||||
|
source files (.py files) via the ``mpy-cross`` program. For some architectures
|
||||||
|
an .mpy file can also contain native machine code, which can be generated in
|
||||||
|
a variety of ways, most notably from C source code.
|
||||||
|
|
||||||
|
Versioning and compatibility of .mpy files
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
A given .mpy file may or may not be compatible with a given MicroPython system.
|
||||||
|
Compatibility is based on the following:
|
||||||
|
|
||||||
|
* Version of the .mpy file: the version of the file must match the version
|
||||||
|
supported by the system loading it.
|
||||||
|
|
||||||
|
* Sub-version of the .mpy file: if the .mpy file contains native machine code
|
||||||
|
then the sub-version of the file must match the version support by the
|
||||||
|
system loading it. Otherwise, if there is no native machine code in the .mpy
|
||||||
|
file, then the sub-version is ignored when loading.
|
||||||
|
|
||||||
|
* Small integer bits: the .mpy file will require a minimum number of bits in
|
||||||
|
a small integer and the system loading it must support at least this many
|
||||||
|
bits.
|
||||||
|
|
||||||
|
* Native architecture: if the .mpy file contains native machine code then
|
||||||
|
it will specify the architecture of that machine code and the system
|
||||||
|
loading it must support execution of that architecture's code.
|
||||||
|
|
||||||
|
If a MicroPython system supports importing .mpy files then the
|
||||||
|
``sys.implementation._mpy`` field will exist and return an integer which
|
||||||
|
encodes the version (lower 8 bits), features and native architecture.
|
||||||
|
|
||||||
|
Trying to import an .mpy file that fails one of the first four tests will
|
||||||
|
raise ``ValueError('incompatible .mpy file')``. Trying to import an .mpy
|
||||||
|
file that fails the native architecture test (if it contains native machine
|
||||||
|
code) will raise ``ValueError('incompatible .mpy arch')``.
|
||||||
|
|
||||||
|
If importing an .mpy file fails then try the following:
|
||||||
|
|
||||||
|
* Determine the .mpy version and flags supported by your MicroPython system
|
||||||
|
by executing::
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys_mpy = sys.implementation._mpy
|
||||||
|
arch = [None, 'x86', 'x64',
|
||||||
|
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
|
||||||
|
'xtensa', 'xtensawin'][sys_mpy >> 10]
|
||||||
|
print('mpy version:', sys_mpy & 0xff)
|
||||||
|
print('mpy flags:', end='')
|
||||||
|
if arch:
|
||||||
|
print(' -march=' + arch, end='')
|
||||||
|
print()
|
||||||
|
|
||||||
|
* Check the validity of the .mpy file by inspecting the first two bytes of
|
||||||
|
the file. The first byte should be an uppercase 'C' and the second byte
|
||||||
|
will be the version number, which should match the system version from above.
|
||||||
|
If it doesn't match then rebuild the .mpy file.
|
||||||
|
|
||||||
|
* Check if the system .mpy version matches the version emitted by ``mpy-cross``
|
||||||
|
that was used to build the .mpy file, found by ``mpy-cross --version``.
|
||||||
|
If it doesn't match then recompile ``mpy-cross`` from the Git repository
|
||||||
|
checked out at the tag (or hash) reported by ``mpy-cross --version``.
|
||||||
|
|
||||||
|
* Make sure you are using the correct ``mpy-cross`` flags, found by the code
|
||||||
|
above, or by inspecting the ``MPY_CROSS_FLAGS`` Makefile variable for the
|
||||||
|
port that you are using.
|
||||||
|
|
||||||
|
The following table shows the correspondence between MicroPython release
|
||||||
|
and .mpy version.
|
||||||
|
|
||||||
|
=================== ============
|
||||||
|
MicroPython release .mpy version
|
||||||
|
=================== ============
|
||||||
|
v1.19 and up 6
|
||||||
|
v1.12 - v1.18 5
|
||||||
|
v1.11 4
|
||||||
|
v1.9.3 - v1.10 3
|
||||||
|
v1.9 - v1.9.2 2
|
||||||
|
v1.5.1 - v1.8.7 0
|
||||||
|
=================== ============
|
||||||
|
|
||||||
|
For completeness, the next table shows the Git commit of the main
|
||||||
|
MicroPython repository at which the .mpy version was changed.
|
||||||
|
|
||||||
|
=================== ========================================
|
||||||
|
.mpy version change Git commit
|
||||||
|
=================== ========================================
|
||||||
|
5 to 6 f2040bfc7ee033e48acef9f289790f3b4e6b74e5
|
||||||
|
4 to 5 5716c5cf65e9b2cb46c2906f40302401bdd27517
|
||||||
|
3 to 4 9a5f92ea72754c01cc03e5efcdfe94021120531e
|
||||||
|
2 to 3 ff93fd4f50321c6190e1659b19e64fef3045a484
|
||||||
|
1 to 2 dd11af209d226b7d18d5148b239662e30ed60bad
|
||||||
|
0 to 1 6a11048af1d01c78bdacddadd1b72dc7ba7c6478
|
||||||
|
initial version 0 d8c834c95d506db979ec871417de90b7951edc30
|
||||||
|
=================== ========================================
|
||||||
|
|
||||||
|
Binary encoding of .mpy files
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
MicroPython .mpy files are a binary container format with code objects (bytecode
|
||||||
|
and native machine code) stored internally in a nested hierarchy. The code for
|
||||||
|
the outer module is stored first, and then its children follow. Each child may
|
||||||
|
have further children, for example in the case of a class having methods, or a
|
||||||
|
function defining a lambda or comprehension. To keep files small while still
|
||||||
|
providing a large range of possible values it uses the concept of a
|
||||||
|
variably-encoded-unsigned-integer (vuint) in many places. Similar to utf-8
|
||||||
|
encoding, this encoding stores 7 bits per byte with the 8th bit (MSB) set
|
||||||
|
if one or more bytes follow. The bits of the unsigned integer are stored
|
||||||
|
in the vuint in LSB form.
|
||||||
|
|
||||||
|
The top-level of an .mpy file consists of three parts:
|
||||||
|
|
||||||
|
* The header.
|
||||||
|
|
||||||
|
* The global qstr and constant tables.
|
||||||
|
|
||||||
|
* The raw-code for the outer scope of the module.
|
||||||
|
This outer scope is executed when the .mpy file is imported.
|
||||||
|
|
||||||
|
You can inspect the contents of a .mpy file by using ``mpy-tool.py``, for
|
||||||
|
example (run from the root of the main MicroPython repository)::
|
||||||
|
|
||||||
|
$ ./tools/mpy-tool.py -xd myfile.mpy
|
||||||
|
|
||||||
|
The header
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
The .mpy header is:
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
byte value 0x43 (ASCII 'C')
|
||||||
|
byte .mpy version number
|
||||||
|
byte feature flags
|
||||||
|
byte number of bits in a small int
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
The global qstr and constant tables
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
An .mpy file contains a single qstr table, and a single constant object table.
|
||||||
|
These are global to the .mpy file, they are referenced by all nested raw-code
|
||||||
|
objects. The qstr table maps internal qstr number (internal to the .mpy file)
|
||||||
|
to the resolved qstr number of the runtime that the .mpy file is imported into.
|
||||||
|
This links the .mpy file with the rest of the system that it executes within.
|
||||||
|
The constant object table is populated with references to all constant objects
|
||||||
|
that the .mpy file needs.
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
vuint number of qstrs
|
||||||
|
vuint number of constant objects
|
||||||
|
... qstr data
|
||||||
|
... encoded constant objects
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
Raw code elements
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A raw-code element contains code, either bytecode or native machine code. Its
|
||||||
|
contents are:
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
vuint type, size and whether there are sub-raw-code elements
|
||||||
|
... code (bytecode or machine code)
|
||||||
|
vuint number of sub-raw-code elements (only if non-zero)
|
||||||
|
... sub-raw-code elements
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
The first vuint in a raw-code element encodes the type of code stored in this
|
||||||
|
element (the two least-significant bits), whether this raw-code has any
|
||||||
|
children (the third least-significant bit), and the length of the code that
|
||||||
|
follows (the amount of RAM to allocate for it).
|
||||||
|
|
||||||
|
Following the vuint comes the code itself. Unless the code type is viper code
|
||||||
|
with relocations, this code is constant data and does not need to be modified.
|
||||||
|
|
||||||
|
If this raw-code has any children (as indicated by a bit in the first vuint),
|
||||||
|
following the code comes a vuint counting the number of sub-raw-code elements.
|
||||||
|
|
||||||
|
Finally any sub-raw-code elements are stored, recursively.
|
@ -1,6 +1,13 @@
|
|||||||
# Derived from code on Eric Holscher's blog, found at:
|
# Derived from code on Eric Holscher's blog, found at:
|
||||||
# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/
|
# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
def render_with_jinja(docname, source):
|
||||||
|
if re.search('^\s*.. jinja$', source[0], re.M):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def rstjinja(app, docname, source):
|
def rstjinja(app, docname, source):
|
||||||
"""
|
"""
|
||||||
Render our pages as a jinja template for fancy templating goodness.
|
Render our pages as a jinja template for fancy templating goodness.
|
||||||
@ -9,12 +16,12 @@ def rstjinja(app, docname, source):
|
|||||||
if app.builder.format not in ("html", "latex"):
|
if app.builder.format not in ("html", "latex"):
|
||||||
return
|
return
|
||||||
|
|
||||||
# we only want our one jinja template to run through this func
|
# we only want specific files to run through this func
|
||||||
if "shared-bindings/support_matrix" not in docname:
|
if not render_with_jinja(docname, source):
|
||||||
return
|
return
|
||||||
|
|
||||||
src = rendered = source[0]
|
src = rendered = source[0]
|
||||||
print(docname)
|
print(f"rendering {docname} as jinja templates")
|
||||||
|
|
||||||
if app.builder.format == "html":
|
if app.builder.format == "html":
|
||||||
rendered = app.builder.templates.render_string(
|
rendered = app.builder.templates.render_string(
|
||||||
|
@ -69,28 +69,23 @@ ADDITIONAL_MODULES = {
|
|||||||
"array": "CIRCUITPY_ARRAY",
|
"array": "CIRCUITPY_ARRAY",
|
||||||
# always available, so depend on something that's always 1.
|
# always available, so depend on something that's always 1.
|
||||||
"builtins": "CIRCUITPY",
|
"builtins": "CIRCUITPY",
|
||||||
|
"builtins.pow3": "CIRCUITPY_BUILTINS_POW3",
|
||||||
|
"busio.SPI": "CIRCUITPY_BUSIO_SPI",
|
||||||
|
"busio.UART": "CIRCUITPY_BUSIO_UART",
|
||||||
"collections": "CIRCUITPY_COLLECTIONS",
|
"collections": "CIRCUITPY_COLLECTIONS",
|
||||||
"fontio": "CIRCUITPY_DISPLAYIO",
|
"fontio": "CIRCUITPY_DISPLAYIO",
|
||||||
"io": "CIRCUITPY_IO",
|
"io": "CIRCUITPY_IO",
|
||||||
|
"keypad.KeyMatrix": "CIRCUITPY_KEYPAD_KEYMATRIX",
|
||||||
|
"keypad.Keys": "CIRCUITPY_KEYPAD_KEYS",
|
||||||
|
"keypad.ShiftRegisterKeys": "CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS",
|
||||||
|
"os.getenv": "CIRCUITPY_OS_GETENV",
|
||||||
"select": "MICROPY_PY_USELECT_SELECT",
|
"select": "MICROPY_PY_USELECT_SELECT",
|
||||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
|
||||||
"sys": "CIRCUITPY_SYS",
|
"sys": "CIRCUITPY_SYS",
|
||||||
|
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||||
"usb": "CIRCUITPY_USB_HOST",
|
"usb": "CIRCUITPY_USB_HOST",
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULES_NOT_IN_BINDINGS = [
|
MODULES_NOT_IN_BINDINGS = [ "binascii", "errno", "json", "re", "ulab" ]
|
||||||
"_asyncio",
|
|
||||||
"array",
|
|
||||||
"binascii",
|
|
||||||
"builtins",
|
|
||||||
"collections",
|
|
||||||
"errno",
|
|
||||||
"json",
|
|
||||||
"re",
|
|
||||||
"select",
|
|
||||||
"sys",
|
|
||||||
"ulab",
|
|
||||||
]
|
|
||||||
|
|
||||||
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
|
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
|
||||||
"""Files and dirs at the root of a frozen directory that should be ignored.
|
"""Files and dirs at the root of a frozen directory that should be ignored.
|
||||||
@ -117,7 +112,7 @@ def get_bindings():
|
|||||||
bindings_modules = []
|
bindings_modules = []
|
||||||
for d in get_circuitpython_root_dir().glob("ports/*/bindings"):
|
for d in get_circuitpython_root_dir().glob("ports/*/bindings"):
|
||||||
bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir())
|
bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir())
|
||||||
return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS
|
return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS + list(ADDITIONAL_MODULES.keys())
|
||||||
|
|
||||||
|
|
||||||
def get_board_mapping():
|
def get_board_mapping():
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in btree so it can coexist)
|
|
||||||
MOD = btree_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = btree_c.c btree_py.py
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
BTREE_DIR = $(MPY_DIR)/lib/berkeley-db-1.xx
|
|
||||||
BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error="(void)" -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA)
|
|
||||||
CFLAGS += -I$(BTREE_DIR)/PORT/include
|
|
||||||
CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS)
|
|
||||||
|
|
||||||
SRC += $(addprefix $(realpath $(BTREE_DIR))/,\
|
|
||||||
btree/bt_close.c \
|
|
||||||
btree/bt_conv.c \
|
|
||||||
btree/bt_delete.c \
|
|
||||||
btree/bt_get.c \
|
|
||||||
btree/bt_open.c \
|
|
||||||
btree/bt_overflow.c \
|
|
||||||
btree/bt_page.c \
|
|
||||||
btree/bt_put.c \
|
|
||||||
btree/bt_search.c \
|
|
||||||
btree/bt_seq.c \
|
|
||||||
btree/bt_split.c \
|
|
||||||
btree/bt_utils.c \
|
|
||||||
mpool/mpool.c \
|
|
||||||
)
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
||||||
|
|
||||||
# btree needs gnu99 defined
|
|
||||||
CFLAGS += -std=gnu99
|
|
@ -1,148 +0,0 @@
|
|||||||
#define MICROPY_PY_BTREE (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memcpy(void *dst, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dst, src, n);
|
|
||||||
}
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dest, src, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *malloc(size_t n) {
|
|
||||||
void *ptr = m_malloc(n, false);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
void *realloc(void *ptr, size_t n) {
|
|
||||||
mp_printf(&mp_plat_print, "UNDEF %d\n", __LINE__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
void *calloc(size_t n, size_t m) {
|
|
||||||
void *ptr = m_malloc(n * m, false);
|
|
||||||
// memory already cleared by conservative GC
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(void *ptr) {
|
|
||||||
m_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void abort_(void) {
|
|
||||||
nlr_raise(mp_obj_new_exception(mp_load_global(MP_QSTR_RuntimeError)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int native_errno;
|
|
||||||
#if defined(__linux__)
|
|
||||||
int *__errno_location (void)
|
|
||||||
#else
|
|
||||||
int *__errno (void)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return &native_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
|
|
||||||
if (out_sz == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return out_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
|
|
||||||
if (out_sz == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return out_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
|
|
||||||
const mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
struct mp_stream_seek_t seek_s;
|
|
||||||
seek_s.offset = offset;
|
|
||||||
seek_s.whence = whence;
|
|
||||||
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &native_errno);
|
|
||||||
if (res == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return seek_s.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_stream_posix_fsync(void *stream) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno);
|
|
||||||
if (res == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_full_type_t btree_type;
|
|
||||||
|
|
||||||
#include "extmod/modbtree.c"
|
|
||||||
|
|
||||||
mp_map_elem_t btree_locals_dict_table[8];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_open(size_t n_args, const mp_obj_t *args) {
|
|
||||||
// Make sure we got a stream object
|
|
||||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
|
||||||
|
|
||||||
BTREEINFO openinfo = {0};
|
|
||||||
openinfo.flags = mp_obj_get_int(args[1]);
|
|
||||||
openinfo.cachesize = mp_obj_get_int(args[2]);
|
|
||||||
openinfo.psize = mp_obj_get_int(args[3]);
|
|
||||||
openinfo.minkeypage = mp_obj_get_int(args[4]);
|
|
||||||
DB *db = __bt_open(MP_OBJ_TO_PTR(args[0]), &btree_stream_fvtable, &openinfo, 0);
|
|
||||||
if (db == NULL) {
|
|
||||||
mp_raise_OSError(native_errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(btree_new(db, args[0]));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
btree_type.base.type = (void*)&mp_fun_table.type_type;
|
|
||||||
btree_type.flags = MP_TYPE_FLAG_EXTENDED;
|
|
||||||
btree_type.name = MP_QSTR_btree;
|
|
||||||
btree_type.print = btree_print;
|
|
||||||
btree_type.ext[0].getiter = btree_getiter;
|
|
||||||
btree_type.ext[0].iternext = btree_iternext;
|
|
||||||
btree_type.ext[0].binary_op = btree_binary_op;
|
|
||||||
btree_type.ext[0].subscr = btree_subscr;
|
|
||||||
btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) };
|
|
||||||
btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) };
|
|
||||||
btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) };
|
|
||||||
btree_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_put), MP_OBJ_FROM_PTR(&btree_put_obj) };
|
|
||||||
btree_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_seq), MP_OBJ_FROM_PTR(&btree_seq_obj) };
|
|
||||||
btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) };
|
|
||||||
btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) };
|
|
||||||
btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) };
|
|
||||||
btree_type.locals_dict = (void*)&btree_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj));
|
|
||||||
mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL));
|
|
||||||
mp_store_global(MP_QSTR_DESC, MP_OBJ_NEW_SMALL_INT(FLAG_DESC));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
# Implemented in Python to support keyword arguments
|
|
||||||
def open(stream, *, flags=0, cachesize=0, pagesize=0, minkeypage=0):
|
|
||||||
return _open(stream, flags, cachesize, pagesize, minkeypage)
|
|
@ -1,13 +1,14 @@
|
|||||||
# Location of top-level MicroPython directory
|
# Location of top-level MicroPython directory
|
||||||
MPY_DIR = ../../..
|
MPY_DIR = ../../..
|
||||||
|
|
||||||
# Name of module (different to built-in framebuf so it can coexist)
|
# Name of module
|
||||||
MOD = framebuf_$(ARCH)
|
MOD = features3
|
||||||
|
|
||||||
# Source files (.c or .py)
|
# Source files (.c or .py)
|
||||||
SRC = framebuf.c
|
SRC = features3.c
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
||||||
ARCH = x64
|
ARCH = x64
|
||||||
|
|
||||||
|
# Include to get the rules for compiling and linking the module
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
include $(MPY_DIR)/py/dynruntime.mk
|
60
examples/natmod/features3/features3.c
Normal file
60
examples/natmod/features3/features3.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* This example demonstrates the following features in a native module:
|
||||||
|
- using types
|
||||||
|
- using constant objects
|
||||||
|
- creating dictionaries
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include the header file to get access to the MicroPython API.
|
||||||
|
#include "py/dynruntime.h"
|
||||||
|
|
||||||
|
// A function that returns a tuple of object types.
|
||||||
|
STATIC mp_obj_t get_types(void) {
|
||||||
|
return mp_obj_new_tuple(9, ((mp_obj_t []) {
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_type),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_NoneType),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_bool),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_int),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_str),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_bytes),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_tuple),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_list),
|
||||||
|
MP_OBJ_FROM_PTR(&mp_type_dict),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_types_obj, get_types);
|
||||||
|
|
||||||
|
// A function that returns a tuple of constant objects.
|
||||||
|
STATIC mp_obj_t get_const_objects(void) {
|
||||||
|
return mp_obj_new_tuple(5, ((mp_obj_t []) {
|
||||||
|
mp_const_none,
|
||||||
|
mp_const_false,
|
||||||
|
mp_const_true,
|
||||||
|
mp_const_empty_bytes,
|
||||||
|
mp_const_empty_tuple,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_const_objects_obj, get_const_objects);
|
||||||
|
|
||||||
|
// A function that creates a dictionary from the given arguments.
|
||||||
|
STATIC mp_obj_t make_dict(size_t n_args, const mp_obj_t *args) {
|
||||||
|
mp_obj_t dict = mp_obj_new_dict(n_args / 2);
|
||||||
|
for (; n_args >= 2; n_args -= 2, args += 2) {
|
||||||
|
mp_obj_dict_store(dict, args[0], args[1]);
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(make_dict_obj, 0, MP_OBJ_FUN_ARGS_MAX, make_dict);
|
||||||
|
|
||||||
|
// This is the entry point and is called when the module is imported.
|
||||||
|
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
||||||
|
// This must be first, it sets up the globals dict and other things.
|
||||||
|
MP_DYNRUNTIME_INIT_ENTRY
|
||||||
|
|
||||||
|
// Make the functions available in the module's namespace.
|
||||||
|
mp_store_global(MP_QSTR_make_dict, MP_OBJ_FROM_PTR(&make_dict_obj));
|
||||||
|
mp_store_global(MP_QSTR_get_types, MP_OBJ_FROM_PTR(&get_types_obj));
|
||||||
|
mp_store_global(MP_QSTR_get_const_objects, MP_OBJ_FROM_PTR(&get_const_objects_obj));
|
||||||
|
|
||||||
|
// This must be last, it restores the globals dict.
|
||||||
|
MP_DYNRUNTIME_INIT_EXIT
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
#define MICROPY_PY_FRAMEBUF (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_obj_full_type_t mp_type_framebuf;
|
|
||||||
|
|
||||||
#include "extmod/modframebuf.c"
|
|
||||||
|
|
||||||
mp_map_elem_t framebuf_locals_dict_table[10];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
mp_type_framebuf.base.type = (void*)&mp_type_type;
|
|
||||||
mp_type_framebuf.flags = MP_TYPE_FLAG_EXTENDED;
|
|
||||||
mp_type_framebuf.name = MP_QSTR_FrameBuffer;
|
|
||||||
mp_type_framebuf.make_new = framebuf_make_new;
|
|
||||||
mp_type_framebuf.ext[0].buffer_p.get_buffer = framebuf_get_buffer;
|
|
||||||
framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) };
|
|
||||||
framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) };
|
|
||||||
framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) };
|
|
||||||
framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) };
|
|
||||||
framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) };
|
|
||||||
framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) };
|
|
||||||
framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) };
|
|
||||||
framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) };
|
|
||||||
framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) };
|
|
||||||
framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) };
|
|
||||||
mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf));
|
|
||||||
mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj));
|
|
||||||
mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB));
|
|
||||||
mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB));
|
|
||||||
mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565));
|
|
||||||
mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB));
|
|
||||||
mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB));
|
|
||||||
mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8));
|
|
||||||
mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB));
|
|
||||||
mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -31,7 +31,4 @@ const mp_obj_module_t example_user_cmodule = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Register the module to make it available in Python.
|
// Register the module to make it available in Python.
|
||||||
// Note: the "1" in the third argument means this module is always enabled.
|
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);
|
||||||
// This "1" can be optionally replaced with a macro like MODULE_CEXAMPLE_ENABLED
|
|
||||||
// which can then be used to conditionally enable this module.
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, 1);
|
|
||||||
|
@ -22,7 +22,4 @@ const mp_obj_module_t cppexample_user_cmodule = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Register the module to make it available in Python.
|
// Register the module to make it available in Python.
|
||||||
// Note: the "1" in the third argument means this module is always enabled.
|
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule);
|
||||||
// This "1" can be optionally replaced with a macro like MODULE_CPPEXAMPLE_ENABLED
|
|
||||||
// which can then be used to conditionally enable this module.
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule, 1);
|
|
||||||
|
@ -6,7 +6,7 @@ SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp
|
|||||||
|
|
||||||
# Add our module directory to the include path.
|
# Add our module directory to the include path.
|
||||||
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
|
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
|
||||||
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
|
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -std=c++11
|
||||||
|
|
||||||
# We use C++ features so have to link against the standard library.
|
# We use C++ features so have to link against the standard library.
|
||||||
LDFLAGS_USERMOD += -lstdc++
|
LDFLAGS_USERMOD += -lstdc++
|
||||||
|
@ -26,7 +26,11 @@
|
|||||||
#ifndef AXTLS_OS_PORT_H
|
#ifndef AXTLS_OS_PORT_H
|
||||||
#define AXTLS_OS_PORT_H
|
#define AXTLS_OS_PORT_H
|
||||||
|
|
||||||
|
#ifndef __ets__
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include "py/stream.h"
|
#include "py/stream.h"
|
||||||
#include "lib/crypto-algorithms/sha256.h"
|
#include "lib/crypto-algorithms/sha256.h"
|
||||||
|
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
# CMake fragment for MicroPython extmod component
|
|
||||||
|
|
||||||
set(MICROPY_EXTMOD_DIR "${MICROPY_DIR}/extmod")
|
|
||||||
set(MICROPY_OOFATFS_DIR "${MICROPY_DIR}/lib/oofatfs")
|
|
||||||
|
|
||||||
set(MICROPY_SOURCE_EXTMOD
|
|
||||||
${MICROPY_DIR}/shared/libc/abort_.c
|
|
||||||
${MICROPY_DIR}/shared/libc/printf.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_bitstream.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_i2c.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_mem.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_pulse.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_pwm.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_signal.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_spi.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modbluetooth.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modbtree.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modframebuf.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modnetwork.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modonewire.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduasyncio.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modubinascii.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moducryptolib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moductypes.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduhashlib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduheapq.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modujson.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduplatform.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modurandom.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modure.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduselect.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modusocket.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modussl_axtls.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modutimeq.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduwebsocket.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduzlib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modwebrepl.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/uos_dupterm.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/utime_mphal.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_blockdev.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat_diskio.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat_file.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_lfs.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_posix.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_posix_file.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_reader.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/virtpin.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/nimble/modbluetooth_nimble.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Library for btree module and associated code
|
|
||||||
|
|
||||||
set(MICROPY_LIB_BERKELEY_DIR "${MICROPY_DIR}/lib/berkeley-db-1.xx")
|
|
||||||
|
|
||||||
if(EXISTS "${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c")
|
|
||||||
add_library(micropy_extmod_btree OBJECT
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_conv.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_debug.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_delete.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_get.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_open.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_overflow.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_page.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_put.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_search.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_seq.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_split.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_utils.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/mpool/mpool.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(micropy_extmod_btree PRIVATE
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/PORT/include
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(micropy_extmod_btree PRIVATE
|
|
||||||
__DBINTERFACE_PRIVATE=1
|
|
||||||
mpool_error=printf
|
|
||||||
abort=abort_
|
|
||||||
"virt_fd_t=void*"
|
|
||||||
)
|
|
||||||
|
|
||||||
# The include directories and compile definitions below are needed to build
|
|
||||||
# modbtree.c and should be added to the main MicroPython target.
|
|
||||||
|
|
||||||
list(APPEND MICROPY_INC_CORE
|
|
||||||
"${MICROPY_LIB_BERKELEY_DIR}/PORT/include"
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND MICROPY_DEF_CORE
|
|
||||||
__DBINTERFACE_PRIVATE=1
|
|
||||||
"virt_fd_t=void*"
|
|
||||||
)
|
|
||||||
endif()
|
|
@ -28,8 +28,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
|
|||||||
lfs1.c \
|
lfs1.c \
|
||||||
lfs1_util.c \
|
lfs1_util.c \
|
||||||
)
|
)
|
||||||
else
|
|
||||||
CFLAGS_MOD += -DMICROPY_VFS_LFS1=0
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MICROPY_VFS_LFS2),1)
|
ifeq ($(MICROPY_VFS_LFS2),1)
|
||||||
@ -39,8 +37,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
|
|||||||
lfs2.c \
|
lfs2.c \
|
||||||
lfs2_util.c \
|
lfs2_util.c \
|
||||||
)
|
)
|
||||||
else
|
|
||||||
CFLAGS_MOD += -DMICROPY_VFS_LFS2=0
|
|
||||||
|
|
||||||
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
|
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
|
||||||
endif
|
endif
|
||||||
|
@ -1,108 +1,128 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 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_STM32_FONT_PETME128_8X8_H
|
#ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
|
|
||||||
static const uint8_t font_petme128_8x8[] = {
|
static const uint8_t font_petme128_8x8[] = {
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32=
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32=
|
||||||
0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=!
|
0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=!
|
||||||
0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34="
|
0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34="
|
||||||
0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=#
|
0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=#
|
||||||
0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$
|
0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$
|
||||||
0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=%
|
0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=%
|
||||||
0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=&
|
0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=&
|
||||||
0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39='
|
0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39='
|
||||||
0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=(
|
0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=(
|
||||||
0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=)
|
0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=)
|
||||||
0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=*
|
0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=*
|
||||||
0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+
|
0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+
|
||||||
0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=,
|
0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=,
|
||||||
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=-
|
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=-
|
||||||
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=.
|
0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=.
|
||||||
0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/
|
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/
|
||||||
0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0
|
0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0
|
||||||
0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1
|
0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1
|
||||||
0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2
|
0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2
|
||||||
0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3
|
0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3
|
||||||
0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4
|
0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4
|
||||||
0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5
|
0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5
|
||||||
0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6
|
0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6
|
||||||
0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7
|
0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7
|
||||||
0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8
|
0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8
|
||||||
0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9
|
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9
|
||||||
0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=:
|
0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=:
|
||||||
0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=;
|
0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=;
|
||||||
0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=<
|
0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=<
|
||||||
0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61==
|
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61==
|
||||||
0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=>
|
0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=>
|
||||||
0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=?
|
0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=?
|
||||||
0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@
|
0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@
|
||||||
0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A
|
0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A
|
||||||
0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B
|
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B
|
||||||
0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C
|
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C
|
||||||
0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D
|
0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D
|
||||||
0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E
|
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E
|
||||||
0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F
|
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F
|
||||||
0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G
|
0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G
|
||||||
0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H
|
0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H
|
||||||
0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I
|
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I
|
||||||
0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J
|
0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J
|
||||||
0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K
|
0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K
|
||||||
0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L
|
0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L
|
||||||
0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M
|
0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M
|
||||||
0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N
|
0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N
|
||||||
0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O
|
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O
|
||||||
0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P
|
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P
|
||||||
0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q
|
0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q
|
||||||
0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R
|
0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R
|
||||||
0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S
|
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S
|
||||||
0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T
|
0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T
|
||||||
0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U
|
0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U
|
||||||
0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V
|
0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V
|
||||||
0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W
|
0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W
|
||||||
0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X
|
0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X
|
||||||
0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y
|
0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y
|
||||||
0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z
|
0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z
|
||||||
0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[
|
0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[
|
||||||
0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\'
|
0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\'
|
||||||
0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=]
|
0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=]
|
||||||
0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^
|
0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^
|
||||||
0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_
|
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_
|
||||||
0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=`
|
0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=`
|
||||||
0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a
|
0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a
|
||||||
0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b
|
0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00, // 98=b
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x6c, 0x28, 0x00, // 99=c
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00, // 100=d
|
||||||
0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e
|
0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e
|
||||||
0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f
|
0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f
|
||||||
0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g
|
0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g
|
||||||
0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h
|
0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h
|
||||||
0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i
|
0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i
|
||||||
0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j
|
0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j
|
||||||
0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k
|
0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k
|
||||||
0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l
|
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l
|
||||||
0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m
|
0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m
|
||||||
0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n
|
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o
|
||||||
0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p
|
0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p
|
||||||
0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q
|
0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q
|
||||||
0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r
|
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r
|
||||||
0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s
|
0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s
|
||||||
0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t
|
0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t
|
||||||
0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u
|
0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u
|
||||||
0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v
|
0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v
|
||||||
0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w
|
0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w
|
||||||
0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x
|
0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x
|
||||||
0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y
|
0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y
|
||||||
0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z
|
0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z
|
||||||
0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={
|
0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={
|
||||||
0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=|
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=|
|
||||||
0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=}
|
0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=}
|
||||||
0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~
|
0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~
|
||||||
0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127
|
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
|
* Copyright (c) 2014-2016 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -23,21 +24,25 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
#ifndef MICROPY_INCLUDED_EXTMOD_MISC_H
|
||||||
|
#define MICROPY_INCLUDED_EXTMOD_MISC_H
|
||||||
|
|
||||||
// These helpers move MicroPython objects and their sub-objects to the long lived portion of the
|
// This file contains cumulative declarations for extmod/ .
|
||||||
// heap.
|
|
||||||
|
|
||||||
#ifndef MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
#include <stddef.h>
|
||||||
#define MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#include "py/objfun.h"
|
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
|
||||||
#include "py/objproperty.h"
|
|
||||||
#include "py/objstr.h"
|
|
||||||
|
|
||||||
mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth);
|
#if MICROPY_PY_OS_DUPTERM
|
||||||
mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth);
|
bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream);
|
||||||
mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth);
|
void mp_uos_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached);
|
||||||
mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str);
|
uintptr_t mp_uos_dupterm_poll(uintptr_t poll_flags);
|
||||||
mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth);
|
int mp_uos_dupterm_rx_chr(void);
|
||||||
|
void mp_uos_dupterm_tx_strn(const char *str, size_t len);
|
||||||
|
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc);
|
||||||
|
#else
|
||||||
|
#define mp_uos_dupterm_tx_strn(s, l)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
#endif // MICROPY_INCLUDED_EXTMOD_MISC_H
|
@ -1,367 +0,0 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h> // for declaration of global errno variable
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/stream.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_BTREE
|
|
||||||
|
|
||||||
#include <db.h>
|
|
||||||
#include <../../btree/btree.h>
|
|
||||||
|
|
||||||
typedef struct _mp_obj_btree_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
mp_obj_t stream; // retain a reference to prevent GC from reclaiming it
|
|
||||||
DB *db;
|
|
||||||
mp_obj_t start_key;
|
|
||||||
mp_obj_t end_key;
|
|
||||||
#define FLAG_END_KEY_INCL 1
|
|
||||||
#define FLAG_DESC 2
|
|
||||||
#define FLAG_ITER_TYPE_MASK 0xc0
|
|
||||||
#define FLAG_ITER_KEYS 0x40
|
|
||||||
#define FLAG_ITER_VALUES 0x80
|
|
||||||
#define FLAG_ITER_ITEMS 0xc0
|
|
||||||
byte flags;
|
|
||||||
byte next_flags;
|
|
||||||
} mp_obj_btree_t;
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_obj_type_t btree_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECK_ERROR(res) \
|
|
||||||
if (res == RET_ERROR) { \
|
|
||||||
mp_raise_OSError(errno); \
|
|
||||||
}
|
|
||||||
|
|
||||||
void __dbpanic(DB *db) {
|
|
||||||
mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
|
|
||||||
mp_obj_btree_t *o = m_new_obj(mp_obj_btree_t);
|
|
||||||
o->base.type = (mp_obj_type_t *)&btree_type;
|
|
||||||
o->stream = stream;
|
|
||||||
o->db = db;
|
|
||||||
o->start_key = mp_const_none;
|
|
||||||
o->end_key = mp_const_none;
|
|
||||||
o->next_flags = 0;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
|
||||||
(void)kind;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
mp_printf(print, "<btree %p>", self->db);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_flush(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_close(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_close(self->db));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
|
|
||||||
val.data = (void *)mp_obj_str_get_data(args[2], &val.size);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_put(self->db, &key, &val, 0));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
if (n_args > 2) {
|
|
||||||
return args[2];
|
|
||||||
} else {
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_get_obj, 2, 3, btree_get);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
int flags = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
|
||||||
DBT key, val;
|
|
||||||
if (n_args > 2) {
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[2], &key.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = __bt_seq(self->db, &key, &val, flags);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t pair_o = mp_obj_new_tuple(2, NULL);
|
|
||||||
mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o);
|
|
||||||
pair->items[0] = mp_obj_new_bytes(key.data, key.size);
|
|
||||||
pair->items[1] = mp_obj_new_bytes(val.data, val.size);
|
|
||||||
return pair_o;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_seq_obj, 2, 4, btree_seq);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_init_iter(size_t n_args, const mp_obj_t *args, byte type) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
self->next_flags = type;
|
|
||||||
self->start_key = mp_const_none;
|
|
||||||
self->end_key = mp_const_none;
|
|
||||||
if (n_args > 1) {
|
|
||||||
self->start_key = args[1];
|
|
||||||
if (n_args > 2) {
|
|
||||||
self->end_key = args[2];
|
|
||||||
if (n_args > 3) {
|
|
||||||
self->next_flags = type | MP_OBJ_SMALL_INT_VALUE(args[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_keys(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_KEYS);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_keys_obj, 1, 4, btree_keys);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_values(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_VALUES);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_values_obj, 1, 4, btree_values);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_items(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_ITEMS);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_items_obj, 1, 4, btree_items);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|
||||||
(void)iter_buf;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
if (self->next_flags != 0) {
|
|
||||||
// If we're called immediately after keys(), values(), or items(),
|
|
||||||
// use their setup for iteration.
|
|
||||||
self->flags = self->next_flags;
|
|
||||||
self->next_flags = 0;
|
|
||||||
} else {
|
|
||||||
// Otherwise, iterate over all keys.
|
|
||||||
self->flags = FLAG_ITER_KEYS;
|
|
||||||
self->start_key = mp_const_none;
|
|
||||||
self->end_key = mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_iternext(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
DBT key, val;
|
|
||||||
int res;
|
|
||||||
bool desc = self->flags & FLAG_DESC;
|
|
||||||
if (self->start_key != MP_OBJ_NULL) {
|
|
||||||
int flags = R_FIRST;
|
|
||||||
if (self->start_key != mp_const_none) {
|
|
||||||
key.data = (void *)mp_obj_str_get_data(self->start_key, &key.size);
|
|
||||||
flags = R_CURSOR;
|
|
||||||
} else if (desc) {
|
|
||||||
flags = R_LAST;
|
|
||||||
}
|
|
||||||
res = __bt_seq(self->db, &key, &val, flags);
|
|
||||||
self->start_key = MP_OBJ_NULL;
|
|
||||||
} else {
|
|
||||||
res = __bt_seq(self->db, &key, &val, desc ? R_PREV : R_NEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
return MP_OBJ_STOP_ITERATION;
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
|
|
||||||
if (self->end_key != mp_const_none) {
|
|
||||||
DBT end_key;
|
|
||||||
end_key.data = (void *)mp_obj_str_get_data(self->end_key, &end_key.size);
|
|
||||||
BTREE *t = self->db->internal;
|
|
||||||
int cmp = t->bt_cmp(&key, &end_key);
|
|
||||||
if (desc) {
|
|
||||||
cmp = -cmp;
|
|
||||||
}
|
|
||||||
if (self->flags & FLAG_END_KEY_INCL) {
|
|
||||||
cmp--;
|
|
||||||
}
|
|
||||||
if (cmp >= 0) {
|
|
||||||
self->end_key = MP_OBJ_NULL;
|
|
||||||
return MP_OBJ_STOP_ITERATION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self->flags & FLAG_ITER_TYPE_MASK) {
|
|
||||||
case FLAG_ITER_KEYS:
|
|
||||||
return mp_obj_new_bytes(key.data, key.size);
|
|
||||||
case FLAG_ITER_VALUES:
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
default: {
|
|
||||||
mp_obj_t pair_o = mp_obj_new_tuple(2, NULL);
|
|
||||||
mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o);
|
|
||||||
pair->items[0] = mp_obj_new_bytes(key.data, key.size);
|
|
||||||
pair->items[1] = mp_obj_new_bytes(val.data, val.size);
|
|
||||||
return pair_o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|
||||||
mp_obj_btree_t *self = mp_obj_cast_to_native_base(self_in, &btree_type);
|
|
||||||
if (value == MP_OBJ_NULL) {
|
|
||||||
// delete
|
|
||||||
DBT key;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
int res = __bt_delete(self->db, &key, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
mp_raise_type(&mp_type_KeyError);
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_const_none;
|
|
||||||
} else if (value == MP_OBJ_SENTINEL) {
|
|
||||||
// load
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
mp_raise_type(&mp_type_KeyError);
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
} else {
|
|
||||||
// store
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
val.data = (void *)mp_obj_str_get_data(value, &val.size);
|
|
||||||
int res = __bt_put(self->db, &key, &val, 0);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in);
|
|
||||||
switch (op) {
|
|
||||||
case MP_BINARY_OP_CONTAINS: {
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(rhs_in, &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bool(res != RET_SPECIAL);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// op not supported
|
|
||||||
return MP_OBJ_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&btree_close_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&btree_flush_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&btree_get_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_put), MP_ROM_PTR(&btree_put_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_seq), MP_ROM_PTR(&btree_seq_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_keys), MP_ROM_PTR(&btree_keys_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_values), MP_ROM_PTR(&btree_values_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_items), MP_ROM_PTR(&btree_items_obj) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC const mp_obj_type_t btree_type = {
|
|
||||||
{ &mp_type_type },
|
|
||||||
// Save on qstr's, reuse same as for module
|
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
|
||||||
.name = MP_QSTR_btree,
|
|
||||||
.print = btree_print,
|
|
||||||
.locals_dict = (void *)&btree_locals_dict,
|
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
|
||||||
.getiter = btree_getiter,
|
|
||||||
.iternext = btree_iternext,
|
|
||||||
.binary_op = btree_binary_op,
|
|
||||||
.subscr = btree_subscr,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC const FILEVTABLE btree_stream_fvtable = {
|
|
||||||
mp_stream_posix_read,
|
|
||||||
mp_stream_posix_write,
|
|
||||||
mp_stream_posix_lseek,
|
|
||||||
mp_stream_posix_fsync
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_flags, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_cachesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_pagesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_minkeypage, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure we got a stream object
|
|
||||||
mp_get_stream_raise(pos_args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
mp_arg_val_t flags;
|
|
||||||
mp_arg_val_t cachesize;
|
|
||||||
mp_arg_val_t pagesize;
|
|
||||||
mp_arg_val_t minkeypage;
|
|
||||||
} args;
|
|
||||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
|
|
||||||
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
|
|
||||||
BTREEINFO openinfo = {0};
|
|
||||||
openinfo.flags = args.flags.u_int;
|
|
||||||
openinfo.cachesize = args.cachesize.u_int;
|
|
||||||
openinfo.psize = args.pagesize.u_int;
|
|
||||||
openinfo.minkeypage = args.minkeypage.u_int;
|
|
||||||
|
|
||||||
DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, /*dflags*/ 0);
|
|
||||||
if (db == NULL) {
|
|
||||||
mp_raise_OSError(errno);
|
|
||||||
}
|
|
||||||
return MP_OBJ_FROM_PTR(btree_new(db, pos_args[0]));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_btree_open_obj, 1, mod_btree_open);
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_btree_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_btree) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_btree_open_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_INCL), MP_ROM_INT(FLAG_END_KEY_INCL) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_DESC), MP_ROM_INT(FLAG_DESC) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_btree = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_btree_globals,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_BTREE
|
|
@ -1,667 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/objtype.h"
|
|
||||||
#include "py/proto.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_FRAMEBUF
|
|
||||||
|
|
||||||
#include "font_petme128_8x8.h"
|
|
||||||
|
|
||||||
typedef struct _mp_obj_framebuf_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
mp_obj_t buf_obj; // need to store this to prevent GC from reclaiming buf
|
|
||||||
void *buf;
|
|
||||||
uint16_t width, height, stride;
|
|
||||||
uint8_t format;
|
|
||||||
} mp_obj_framebuf_t;
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*setpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, uint32_t);
|
|
||||||
typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int);
|
|
||||||
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, unsigned int, unsigned int, uint32_t);
|
|
||||||
|
|
||||||
typedef struct _mp_framebuf_p_t {
|
|
||||||
setpixel_t setpixel;
|
|
||||||
getpixel_t getpixel;
|
|
||||||
fill_rect_t fill_rect;
|
|
||||||
} mp_framebuf_p_t;
|
|
||||||
|
|
||||||
// constants for formats
|
|
||||||
#define FRAMEBUF_MVLSB (0)
|
|
||||||
#define FRAMEBUF_RGB565 (1)
|
|
||||||
#define FRAMEBUF_GS2_HMSB (5)
|
|
||||||
#define FRAMEBUF_GS4_HMSB (2)
|
|
||||||
#define FRAMEBUF_GS8 (6)
|
|
||||||
#define FRAMEBUF_MHLSB (3)
|
|
||||||
#define FRAMEBUF_MHMSB (4)
|
|
||||||
|
|
||||||
// Functions for MHLSB and MHMSB
|
|
||||||
|
|
||||||
STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
size_t index = (x + y * fb->stride) >> 3;
|
|
||||||
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
|
||||||
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
size_t index = (x + y * fb->stride) >> 3;
|
|
||||||
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
|
||||||
return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
unsigned int reverse = fb->format == FRAMEBUF_MHMSB;
|
|
||||||
unsigned int advance = fb->stride >> 3;
|
|
||||||
while (w--) {
|
|
||||||
uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance];
|
|
||||||
unsigned int offset = reverse ? x & 7 : 7 - (x & 7);
|
|
||||||
for (unsigned int hh = h; hh; --hh) {
|
|
||||||
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
b += advance;
|
|
||||||
}
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for MVLSB format
|
|
||||||
|
|
||||||
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
size_t index = (y >> 3) * fb->stride + x;
|
|
||||||
uint8_t offset = y & 0x07;
|
|
||||||
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
while (h--) {
|
|
||||||
uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x];
|
|
||||||
uint8_t offset = y & 0x07;
|
|
||||||
for (unsigned int ww = w; ww; --ww) {
|
|
||||||
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
++y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for RGB565 format
|
|
||||||
|
|
||||||
STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
((uint16_t *)fb->buf)[x + y * fb->stride] = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return ((uint16_t *)fb->buf)[x + y * fb->stride];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride];
|
|
||||||
while (h--) {
|
|
||||||
for (unsigned int ww = w; ww; --ww) {
|
|
||||||
*b++ = col;
|
|
||||||
}
|
|
||||||
b += fb->stride - w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS2_HMSB format
|
|
||||||
|
|
||||||
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
|
|
||||||
uint8_t shift = (x & 0x3) << 1;
|
|
||||||
uint8_t mask = 0x3 << shift;
|
|
||||||
uint8_t color = (col & 0x3) << shift;
|
|
||||||
*pixel = color | (*pixel & (~mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
|
|
||||||
uint8_t shift = (x & 0x3) << 1;
|
|
||||||
return (pixel >> shift) & 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
for (unsigned int xx = x; xx < x + w; xx++) {
|
|
||||||
for (unsigned int yy = y; yy < y + h; yy++) {
|
|
||||||
gs2_hmsb_setpixel(fb, xx, yy, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS4_HMSB format
|
|
||||||
|
|
||||||
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
|
|
||||||
|
|
||||||
if (x % 2) {
|
|
||||||
*pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0);
|
|
||||||
} else {
|
|
||||||
*pixel = ((uint8_t)col << 4) | (*pixel & 0x0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
if (x % 2) {
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
col &= 0x0f;
|
|
||||||
uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
|
|
||||||
uint8_t col_shifted_left = col << 4;
|
|
||||||
uint8_t col_pixel_pair = col_shifted_left | col;
|
|
||||||
unsigned int pixel_count_till_next_line = (fb->stride - w) >> 1;
|
|
||||||
bool odd_x = (x % 2 == 1);
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
unsigned int ww = w;
|
|
||||||
|
|
||||||
if (odd_x && ww > 0) {
|
|
||||||
*pixel_pair = (*pixel_pair & 0xf0) | col;
|
|
||||||
pixel_pair++;
|
|
||||||
ww--;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(pixel_pair, col_pixel_pair, ww >> 1);
|
|
||||||
pixel_pair += ww >> 1;
|
|
||||||
|
|
||||||
if (ww % 2) {
|
|
||||||
*pixel_pair = col_shifted_left | (*pixel_pair & 0x0f);
|
|
||||||
if (!odd_x) {
|
|
||||||
pixel_pair++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_pair += pixel_count_till_next_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS8 format
|
|
||||||
|
|
||||||
STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
*pixel = col & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
while (h--) {
|
|
||||||
memset(pixel, col, w);
|
|
||||||
pixel += fb->stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC const mp_framebuf_p_t formats[] = {
|
|
||||||
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
|
||||||
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
|
||||||
[FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
|
|
||||||
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
|
||||||
[FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
|
|
||||||
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
|
||||||
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
formats[fb->format].setpixel(fb, x, y, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return formats[fb->format].getpixel(fb, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
|
|
||||||
if (h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) {
|
|
||||||
// No operation needed.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clip to the framebuffer
|
|
||||||
int xend = MIN(fb->width, x + w);
|
|
||||||
int yend = MIN(fb->height, y + h);
|
|
||||||
x = MAX(x, 0);
|
|
||||||
y = MAX(y, 0);
|
|
||||||
|
|
||||||
formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_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, 4, 5, false);
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
|
|
||||||
o->base.type = type;
|
|
||||||
o->buf_obj = args[0];
|
|
||||||
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
|
|
||||||
o->buf = bufinfo.buf;
|
|
||||||
|
|
||||||
o->width = mp_obj_get_int(args[1]);
|
|
||||||
o->height = mp_obj_get_int(args[2]);
|
|
||||||
o->format = mp_obj_get_int(args[3]);
|
|
||||||
if (n_args >= 5) {
|
|
||||||
o->stride = mp_obj_get_int(args[4]);
|
|
||||||
} else {
|
|
||||||
o->stride = o->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (o->format) {
|
|
||||||
case FRAMEBUF_MVLSB:
|
|
||||||
case FRAMEBUF_RGB565:
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_MHLSB:
|
|
||||||
case FRAMEBUF_MHMSB:
|
|
||||||
o->stride = (o->stride + 7) & ~7;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS2_HMSB:
|
|
||||||
o->stride = (o->stride + 3) & ~3;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS4_HMSB:
|
|
||||||
o->stride = (o->stride + 1) & ~1;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS8:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Helper to ensure we have the native super class instead of a subclass.
|
|
||||||
static mp_obj_framebuf_t *native_framebuf(mp_obj_t framebuf_obj) {
|
|
||||||
mp_obj_t native_framebuf = mp_obj_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
|
|
||||||
mp_obj_assert_native_inited(native_framebuf);
|
|
||||||
if (native_framebuf == MP_OBJ_NULL) {
|
|
||||||
mp_raise_TypeError(NULL);
|
|
||||||
}
|
|
||||||
return MP_OBJ_TO_PTR(native_framebuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
|
||||||
(void)flags;
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
bufinfo->buf = self->buf;
|
|
||||||
bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1);
|
|
||||||
bufinfo->typecode = 'B'; // view framebuf as bytes
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
mp_int_t col = mp_obj_get_int(col_in);
|
|
||||||
formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t width = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t height = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, width, height, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
if (0 <= x && x < self->width && 0 <= y && y < self->height) {
|
|
||||||
if (n_args == 3) {
|
|
||||||
// get
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y));
|
|
||||||
} else {
|
|
||||||
// set
|
|
||||||
setpixel(self, x, y, mp_obj_get_int(args[3]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t w = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[4]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, w, 1, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t h = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[4]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, 1, h, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t w = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t h = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, w, 1, col);
|
|
||||||
fill_rect(self, x, y + h - 1, w, 1, col);
|
|
||||||
fill_rect(self, x, y, 1, h, col);
|
|
||||||
fill_rect(self, x + w - 1, y, 1, h, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x1 = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y1 = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t x2 = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t y2 = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
mp_int_t dx = x2 - x1;
|
|
||||||
mp_int_t sx;
|
|
||||||
if (dx > 0) {
|
|
||||||
sx = 1;
|
|
||||||
} else {
|
|
||||||
dx = -dx;
|
|
||||||
sx = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t dy = y2 - y1;
|
|
||||||
mp_int_t sy;
|
|
||||||
if (dy > 0) {
|
|
||||||
sy = 1;
|
|
||||||
} else {
|
|
||||||
dy = -dy;
|
|
||||||
sy = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool steep;
|
|
||||||
if (dy > dx) {
|
|
||||||
mp_int_t temp;
|
|
||||||
temp = x1;
|
|
||||||
x1 = y1;
|
|
||||||
y1 = temp;
|
|
||||||
temp = dx;
|
|
||||||
dx = dy;
|
|
||||||
dy = temp;
|
|
||||||
temp = sx;
|
|
||||||
sx = sy;
|
|
||||||
sy = temp;
|
|
||||||
steep = true;
|
|
||||||
} else {
|
|
||||||
steep = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t e = 2 * dy - dx;
|
|
||||||
for (mp_int_t i = 0; i < dx; ++i) {
|
|
||||||
if (steep) {
|
|
||||||
if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) {
|
|
||||||
setpixel(self, y1, x1, col);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) {
|
|
||||||
setpixel(self, x1, y1, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (e >= 0) {
|
|
||||||
y1 += sy;
|
|
||||||
e -= 2 * dx;
|
|
||||||
}
|
|
||||||
x1 += sx;
|
|
||||||
e += 2 * dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) {
|
|
||||||
setpixel(self, x2, y2, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_obj_framebuf_t *source = native_framebuf(args[1]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t key = -1;
|
|
||||||
if (n_args > 4) {
|
|
||||||
key = mp_obj_get_int(args[4]);
|
|
||||||
}
|
|
||||||
mp_obj_framebuf_t *palette = NULL;
|
|
||||||
if (n_args > 5 && args[5] != mp_const_none) {
|
|
||||||
palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args[5], MP_OBJ_FROM_PTR(&mp_type_framebuf)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(x >= self->width) ||
|
|
||||||
(y >= self->height) ||
|
|
||||||
(-x >= source->width) ||
|
|
||||||
(-y >= source->height)
|
|
||||||
) {
|
|
||||||
// Out of bounds, no-op.
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clip.
|
|
||||||
int x0 = MAX(0, x);
|
|
||||||
int y0 = MAX(0, y);
|
|
||||||
int x1 = MAX(0, -x);
|
|
||||||
int y1 = MAX(0, -y);
|
|
||||||
int x0end = MIN(self->width, x + source->width);
|
|
||||||
int y0end = MIN(self->height, y + source->height);
|
|
||||||
|
|
||||||
for (; y0 < y0end; ++y0) {
|
|
||||||
int cx1 = x1;
|
|
||||||
for (int cx0 = x0; cx0 < x0end; ++cx0) {
|
|
||||||
uint32_t col = getpixel(source, cx1, y1);
|
|
||||||
if (palette) {
|
|
||||||
col = getpixel(palette, col, 0);
|
|
||||||
}
|
|
||||||
if (col != (uint32_t)key) {
|
|
||||||
setpixel(self, cx0, y0, col);
|
|
||||||
}
|
|
||||||
++cx1;
|
|
||||||
}
|
|
||||||
++y1;
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 6, framebuf_blit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
mp_int_t xstep = mp_obj_get_int(xstep_in);
|
|
||||||
mp_int_t ystep = mp_obj_get_int(ystep_in);
|
|
||||||
int sx, y, xend, yend, dx, dy;
|
|
||||||
if (xstep < 0) {
|
|
||||||
sx = 0;
|
|
||||||
xend = self->width + xstep;
|
|
||||||
dx = 1;
|
|
||||||
} else {
|
|
||||||
sx = self->width - 1;
|
|
||||||
xend = xstep - 1;
|
|
||||||
dx = -1;
|
|
||||||
}
|
|
||||||
if (ystep < 0) {
|
|
||||||
y = 0;
|
|
||||||
yend = self->height + ystep;
|
|
||||||
dy = 1;
|
|
||||||
} else {
|
|
||||||
y = self->height - 1;
|
|
||||||
yend = ystep - 1;
|
|
||||||
dy = -1;
|
|
||||||
}
|
|
||||||
for (; y != yend; y += dy) {
|
|
||||||
for (int x = sx; x != xend; x += dx) {
|
|
||||||
setpixel(self, x, y, getpixel(self, x - xstep, y - ystep));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
|
|
||||||
// extract arguments
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
const char *str = mp_obj_str_get_str(args[1]);
|
|
||||||
mp_int_t x0 = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t y0 = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = 1;
|
|
||||||
if (n_args >= 5) {
|
|
||||||
col = mp_obj_get_int(args[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop over chars
|
|
||||||
for (; *str; ++str) {
|
|
||||||
// get char and make sure its in range of font
|
|
||||||
int chr = *(uint8_t *)str;
|
|
||||||
if (chr < 32 || chr > 127) {
|
|
||||||
chr = 127;
|
|
||||||
}
|
|
||||||
// get char data
|
|
||||||
const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8];
|
|
||||||
// loop over char data
|
|
||||||
for (int j = 0; j < 8; j++, x0++) {
|
|
||||||
if (0 <= x0 && x0 < self->width) { // clip x
|
|
||||||
uint vline_data = chr_data[j]; // each byte is a column of 8 pixels, LSB at top
|
|
||||||
for (int y = y0; vline_data; vline_data >>= 1, y++) { // scan over vertical column
|
|
||||||
if (vline_data & 1) { // only draw if pixel set
|
|
||||||
if (0 <= y && y < self->height) { // clip y
|
|
||||||
setpixel(self, x0, y, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text);
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&framebuf_fill_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&framebuf_fill_rect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&framebuf_pixel_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_hline), MP_ROM_PTR(&framebuf_hline_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_vline), MP_ROM_PTR(&framebuf_vline_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) },
|
|
||||||
};
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf = {
|
|
||||||
{ &mp_type_type },
|
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
|
||||||
.name = MP_QSTR_FrameBuffer,
|
|
||||||
.make_new = framebuf_make_new,
|
|
||||||
.locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict,
|
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
|
||||||
.buffer_p = { .get_buffer = framebuf_get_buffer },
|
|
||||||
),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this factory function is provided for backwards compatibility with old FrameBuffer1 class
|
|
||||||
STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
|
|
||||||
o->base.type = (mp_obj_type_t *)&mp_type_framebuf;
|
|
||||||
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
|
|
||||||
o->buf = bufinfo.buf;
|
|
||||||
|
|
||||||
o->width = mp_obj_get_int(args[1]);
|
|
||||||
o->height = mp_obj_get_int(args[2]);
|
|
||||||
o->format = FRAMEBUF_MVLSB;
|
|
||||||
if (n_args >= 4) {
|
|
||||||
o->stride = mp_obj_get_int(args[3]);
|
|
||||||
} else {
|
|
||||||
o->stride = o->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(legacy_framebuffer1_obj, 3, 4, legacy_framebuffer1);
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebuf) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer), MP_ROM_PTR(&mp_type_framebuf) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS8), MP_ROM_INT(FRAMEBUF_GS8) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_framebuf = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&framebuf_module_globals,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_FRAMEBUF
|
|
@ -1,145 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Damien P. George
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "py/obj.h"
|
|
||||||
#include "py/mphal.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_ONEWIRE
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
// Low-level 1-Wire routines
|
|
||||||
|
|
||||||
#define TIMING_RESET1 (480)
|
|
||||||
#define TIMING_RESET2 (70)
|
|
||||||
#define TIMING_RESET3 (410)
|
|
||||||
#define TIMING_READ1 (5)
|
|
||||||
#define TIMING_READ2 (5)
|
|
||||||
#define TIMING_READ3 (40)
|
|
||||||
#define TIMING_WRITE1 (10)
|
|
||||||
#define TIMING_WRITE2 (50)
|
|
||||||
#define TIMING_WRITE3 (10)
|
|
||||||
|
|
||||||
STATIC int onewire_bus_reset(mp_hal_pin_obj_t pin) {
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us(TIMING_RESET1);
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_RESET2);
|
|
||||||
int status = !mp_hal_pin_read(pin);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
mp_hal_delay_us(TIMING_RESET3);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC int onewire_bus_readbit(mp_hal_pin_obj_t pin) {
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ1);
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ2);
|
|
||||||
int value = mp_hal_pin_read(pin);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ3);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void onewire_bus_writebit(mp_hal_pin_obj_t pin, int value) {
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE1);
|
|
||||||
if (value) {
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
}
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE2);
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE3);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
// MicroPython bindings
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_reset(mp_obj_t pin_in) {
|
|
||||||
return mp_obj_new_bool(onewire_bus_reset(mp_hal_get_pin_obj(pin_in)));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_reset_obj, onewire_reset);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_readbit(mp_obj_t pin_in) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(onewire_bus_readbit(mp_hal_get_pin_obj(pin_in)));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbit_obj, onewire_readbit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_readbyte(mp_obj_t pin_in) {
|
|
||||||
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in);
|
|
||||||
uint8_t value = 0;
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
value |= onewire_bus_readbit(pin) << i;
|
|
||||||
}
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(value);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbyte_obj, onewire_readbyte);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_writebit(mp_obj_t pin_in, mp_obj_t value_in) {
|
|
||||||
onewire_bus_writebit(mp_hal_get_pin_obj(pin_in), mp_obj_get_int(value_in));
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebit_obj, onewire_writebit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_writebyte(mp_obj_t pin_in, mp_obj_t value_in) {
|
|
||||||
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in);
|
|
||||||
int value = mp_obj_get_int(value_in);
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
onewire_bus_writebit(pin, value & 1);
|
|
||||||
value >>= 1;
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebyte_obj, onewire_writebyte);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_crc8(mp_obj_t data) {
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
|
||||||
uint8_t crc = 0;
|
|
||||||
for (size_t i = 0; i < bufinfo.len; ++i) {
|
|
||||||
uint8_t byte = ((uint8_t *)bufinfo.buf)[i];
|
|
||||||
for (int b = 0; b < 8; ++b) {
|
|
||||||
uint8_t fb_bit = (crc ^ byte) & 0x01;
|
|
||||||
if (fb_bit == 0x01) {
|
|
||||||
crc = crc ^ 0x18;
|
|
||||||
}
|
|
||||||
crc = (crc >> 1) & 0x7f;
|
|
||||||
if (fb_bit == 0x01) {
|
|
||||||
crc = crc | 0x80;
|
|
||||||
}
|
|
||||||
byte = byte >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(crc);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_crc8_obj, onewire_crc8);
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t onewire_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewire) },
|
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&onewire_reset_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_readbit), MP_ROM_PTR(&onewire_readbit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_readbyte), MP_ROM_PTR(&onewire_readbyte_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_writebit), MP_ROM_PTR(&onewire_writebit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_writebyte), MP_ROM_PTR(&onewire_writebyte_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_crc8), MP_ROM_PTR(&onewire_crc8_obj) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(onewire_module_globals, onewire_module_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_onewire = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&onewire_module_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_ONEWIRE
|
|
@ -29,14 +29,14 @@
|
|||||||
#include "py/pairheap.h"
|
#include "py/pairheap.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
|
||||||
|
#if MICROPY_PY_UASYNCIO
|
||||||
|
|
||||||
#if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__))
|
#if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__))
|
||||||
#include "shared-bindings/supervisor/__init__.h"
|
#include "shared-bindings/supervisor/__init__.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "supervisor/shared/translate/translate.h"
|
#include "supervisor/shared/translate/translate.h"
|
||||||
|
|
||||||
#if MICROPY_PY_UASYNCIO
|
|
||||||
|
|
||||||
// Used when task cannot be guaranteed to be non-NULL.
|
// Used when task cannot be guaranteed to be non-NULL.
|
||||||
#define TASK_PAIRHEAP(task) ((task) ? &(task)->pairheap : NULL)
|
#define TASK_PAIRHEAP(task) ((task) ? &(task)->pairheap : NULL)
|
||||||
|
|
||||||
@ -70,6 +70,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// Ticks for task ordering in pairing heap
|
// Ticks for task ordering in pairing heap
|
||||||
|
|
||||||
|
// CIRCUITPY-style ticks
|
||||||
#define _TICKS_PERIOD (1lu << 29)
|
#define _TICKS_PERIOD (1lu << 29)
|
||||||
#define _TICKS_MAX (_TICKS_PERIOD - 1)
|
#define _TICKS_MAX (_TICKS_PERIOD - 1)
|
||||||
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
|
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
|
||||||
@ -105,8 +106,7 @@ STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
|
|||||||
STATIC mp_obj_t task_queue_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 task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||||
mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t);
|
mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
|
||||||
self->base.type = type;
|
|
||||||
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
|
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
|
||||||
task->data = mp_const_none;
|
task->data = mp_const_none;
|
||||||
@ -134,9 +134,9 @@ STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
|
|||||||
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
|
STATIC mp_obj_t task_queue_pop(mp_obj_t self_in) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
|
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
|
||||||
if (head == NULL) {
|
if (head == NULL) {
|
||||||
@ -145,7 +145,7 @@ STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
|
|||||||
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
|
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
|
||||||
return MP_OBJ_FROM_PTR(head);
|
return MP_OBJ_FROM_PTR(head);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_obj, task_queue_pop);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
|
STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
@ -157,10 +157,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_queue_remove_obj, task_queue_remove);
|
|||||||
|
|
||||||
STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
||||||
|
|
||||||
|
// CIRCUITPYTHON: remove these after the bundle need not support 8.x
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
||||||
|
|
||||||
@ -223,18 +227,18 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
|
|||||||
// Not on the main running queue, remove the task from the queue it's on.
|
// Not on the main running queue, remove the task from the queue it's on.
|
||||||
dest[2] = MP_OBJ_FROM_PTR(self);
|
dest[2] = MP_OBJ_FROM_PTR(self);
|
||||||
mp_call_method_n_kw(1, 0, dest);
|
mp_call_method_n_kw(1, 0, dest);
|
||||||
// _task_queue.push_head(self)
|
// _task_queue.push(self)
|
||||||
dest[0] = _task_queue;
|
dest[0] = _task_queue;
|
||||||
dest[1] = MP_OBJ_FROM_PTR(self);
|
dest[1] = MP_OBJ_FROM_PTR(self);
|
||||||
task_queue_push_sorted(2, dest);
|
task_queue_push(2, dest);
|
||||||
} else if (ticks_diff(self->ph_key, ticks()) > 0) {
|
} else if (ticks_diff(self->ph_key, ticks()) > 0) {
|
||||||
// On the main running queue but scheduled in the future, so bring it forward to now.
|
// On the main running queue but scheduled in the future, so bring it forward to now.
|
||||||
// _task_queue.remove(self)
|
// _task_queue.remove(self)
|
||||||
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
|
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
|
||||||
// _task_queue.push_head(self)
|
// _task_queue.push(self)
|
||||||
dest[0] = _task_queue;
|
dest[0] = _task_queue;
|
||||||
dest[1] = MP_OBJ_FROM_PTR(self);
|
dest[1] = MP_OBJ_FROM_PTR(self);
|
||||||
task_queue_push_sorted(2, dest);
|
task_queue_push(2, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
|
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
|
||||||
@ -243,6 +247,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
|
||||||
|
|
||||||
|
// CIRCUITPY provides __await__().
|
||||||
STATIC mp_obj_t task_await(mp_obj_t self_in) {
|
STATIC mp_obj_t task_await(mp_obj_t self_in) {
|
||||||
return task_getiter(self_in, NULL);
|
return task_getiter(self_in, NULL);
|
||||||
}
|
}
|
||||||
@ -266,6 +271,7 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||||||
dest[1] = self_in;
|
dest[1] = self_in;
|
||||||
} else if (attr == MP_QSTR_ph_key) {
|
} else if (attr == MP_QSTR_ph_key) {
|
||||||
dest[0] = self->ph_key;
|
dest[0] = self->ph_key;
|
||||||
|
// CIRCUITPY provides __await__().
|
||||||
} else if (attr == MP_QSTR___await__) {
|
} else if (attr == MP_QSTR___await__) {
|
||||||
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
|
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
|
||||||
dest[1] = self_in;
|
dest[1] = self_in;
|
||||||
@ -291,6 +297,9 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|||||||
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
||||||
// Allocate the waiting queue.
|
// Allocate the waiting queue.
|
||||||
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
||||||
|
} else if (mp_obj_get_type(self->state) != &task_queue_type) {
|
||||||
|
// Task has state used for another purpose, so can't also wait on it.
|
||||||
|
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't wait"));
|
||||||
}
|
}
|
||||||
return self_in;
|
return self_in;
|
||||||
}
|
}
|
||||||
@ -298,6 +307,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|||||||
STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
||||||
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (TASK_IS_DONE(self)) {
|
if (TASK_IS_DONE(self)) {
|
||||||
|
// CIRCUITPY
|
||||||
if (self->data == mp_const_none) {
|
if (self->data == mp_const_none) {
|
||||||
// Task finished but has already been sent to the loop's exception handler.
|
// Task finished but has already been sent to the loop's exception handler.
|
||||||
mp_raise_StopIteration(MP_OBJ_NULL);
|
mp_raise_StopIteration(MP_OBJ_NULL);
|
||||||
@ -309,7 +319,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
|||||||
// Put calling task on waiting queue.
|
// Put calling task on waiting queue.
|
||||||
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
|
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
|
||||||
mp_obj_t args[2] = { self->state, cur_task };
|
mp_obj_t args[2] = { self->state, cur_task };
|
||||||
task_queue_push_sorted(2, args);
|
task_queue_push(2, args);
|
||||||
// Set calling task's data to this task that it waits on, to double-link it.
|
// Set calling task's data to this task that it waits on, to double-link it.
|
||||||
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
|
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
|
||||||
}
|
}
|
||||||
@ -347,6 +357,6 @@ const mp_obj_module_t mp_module_uasyncio = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio, MICROPY_PY_UASYNCIO);
|
MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UASYNCIO
|
#endif // MICROPY_PY_UASYNCIO
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: 2022 Beat Ludin for Adafruit Industries
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -13,6 +33,8 @@
|
|||||||
|
|
||||||
#include "supervisor/shared/translate/translate.h"
|
#include "supervisor/shared/translate/translate.h"
|
||||||
|
|
||||||
|
#if MICROPY_PY_UBINASCII
|
||||||
|
|
||||||
static void check_not_unicode(const mp_obj_t arg) {
|
static void check_not_unicode(const mp_obj_t arg) {
|
||||||
#if MICROPY_CPYTHON_COMPAT
|
#if MICROPY_CPYTHON_COMPAT
|
||||||
if (mp_obj_is_str(arg)) {
|
if (mp_obj_is_str(arg)) {
|
||||||
@ -20,7 +42,6 @@ static void check_not_unicode(const mp_obj_t arg) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
||||||
// First argument is the data to convert.
|
// First argument is the data to convert.
|
||||||
// Second argument is an optional separator to be used between values.
|
// Second argument is an optional separator to be used between values.
|
||||||
@ -154,13 +175,21 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
|
||||||
|
|
||||||
STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
check_not_unicode(data);
|
enum { ARG_newline };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_newline, MP_ARG_BOOL, {.u_bool = true} },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
uint8_t newline = args[ARG_newline].u_bool;
|
||||||
|
check_not_unicode(pos_args[0]);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1);
|
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + newline);
|
||||||
|
|
||||||
// First pass, we convert input buffer to numeric base 64 values
|
// First pass, we convert input buffer to numeric base 64 values
|
||||||
byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
|
byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
|
||||||
@ -186,7 +215,7 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
|||||||
|
|
||||||
// Second pass, we convert number base 64 values to actual base64 ascii encoding
|
// Second pass, we convert number base 64 values to actual base64 ascii encoding
|
||||||
out = (byte *)vstr.buf;
|
out = (byte *)vstr.buf;
|
||||||
for (mp_uint_t j = vstr.len - 1; j--;) {
|
for (mp_uint_t j = vstr.len - newline; j--;) {
|
||||||
if (*out < 26) {
|
if (*out < 26) {
|
||||||
*out += 'A';
|
*out += 'A';
|
||||||
} else if (*out < 52) {
|
} else if (*out < 52) {
|
||||||
@ -202,10 +231,15 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
|||||||
}
|
}
|
||||||
out++;
|
out++;
|
||||||
}
|
}
|
||||||
|
if (newline) {
|
||||||
*out = '\n';
|
*out = '\n';
|
||||||
|
}
|
||||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64);
|
||||||
|
|
||||||
|
// CIRCUITPY uses a self-contained implementation of CRC32,
|
||||||
|
// instead of depending on uzlib, like MicroPython.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CRC32 checksum
|
* CRC32 checksum
|
||||||
@ -296,4 +330,6 @@ const mp_obj_module_t mp_module_ubinascii = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii, MICROPY_PY_UBINASCII);
|
MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii);
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_UBINASCII
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014-2018 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2018 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -76,8 +97,7 @@ STATIC NORETURN void syntax_error(void) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uctypes_struct_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 uctypes_struct_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, 2, 3, false);
|
mp_arg_check_num(n_args, n_kw, 2, 3, false);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, type);
|
||||||
o->base.type = type;
|
|
||||||
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
|
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
|
||||||
o->desc = args[1];
|
o->desc = args[1];
|
||||||
o->flags = LAYOUT_NATIVE;
|
o->flags = LAYOUT_NATIVE;
|
||||||
@ -444,8 +464,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
|||||||
|
|
||||||
switch (agg_type) {
|
switch (agg_type) {
|
||||||
case STRUCT: {
|
case STRUCT: {
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = sub->items[1];
|
o->desc = sub->items[1];
|
||||||
o->addr = self->addr + offset;
|
o->addr = self->addr + offset;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -460,8 +479,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
|||||||
MP_FALLTHROUGH
|
MP_FALLTHROUGH
|
||||||
}
|
}
|
||||||
case PTR: {
|
case PTR: {
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = MP_OBJ_FROM_PTR(sub);
|
o->desc = MP_OBJ_FROM_PTR(sub);
|
||||||
o->addr = self->addr + offset;
|
o->addr = self->addr + offset;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -533,8 +551,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
|||||||
} else if (value == MP_OBJ_SENTINEL) {
|
} else if (value == MP_OBJ_SENTINEL) {
|
||||||
mp_uint_t dummy = 0;
|
mp_uint_t dummy = 0;
|
||||||
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
|
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = t->items[2];
|
o->desc = t->items[2];
|
||||||
o->addr = self->addr + size * index;
|
o->addr = self->addr + size * index;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -551,8 +568,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
|||||||
} else {
|
} else {
|
||||||
mp_uint_t dummy = 0;
|
mp_uint_t dummy = 0;
|
||||||
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
|
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = t->items[1];
|
o->desc = t->items[1];
|
||||||
o->addr = p + size * index;
|
o->addr = p + size * index;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -706,4 +722,6 @@ const mp_obj_module_t mp_module_uctypes = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -39,7 +60,6 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct _mp_obj_hash_t {
|
typedef struct _mp_obj_hash_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
bool final; // if set, update and digest raise an exception
|
bool final; // if set, update and digest raise an exception
|
||||||
@ -65,8 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha256_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 uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
|
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
|
||||||
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
|
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
|
||||||
@ -105,13 +124,11 @@ static void check_not_unicode(const mp_obj_t arg) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_PY_UHASHLIB_SHA256
|
|
||||||
#include "lib/crypto-algorithms/sha256.c"
|
#include "lib/crypto-algorithms/sha256.c"
|
||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha256_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 uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
sha256_init((CRYAL_SHA256_CTX *)o->state);
|
sha256_init((CRYAL_SHA256_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -159,16 +176,13 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MICROPY_PY_UHASHLIB_SHA1
|
#if MICROPY_PY_UHASHLIB_SHA1
|
||||||
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
|
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
|
||||||
|
|
||||||
#if MICROPY_SSL_AXTLS
|
#if MICROPY_SSL_AXTLS
|
||||||
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
STATIC mp_obj_t uhashlib_sha1_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, kw_args, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
SHA1_Init((SHA1_CTX *)o->state);
|
SHA1_Init((SHA1_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -178,7 +192,6 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
|
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
|
||||||
check_not_unicode(arg);
|
|
||||||
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
uhashlib_ensure_not_final(self);
|
uhashlib_ensure_not_final(self);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
@ -208,8 +221,7 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha1_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 uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
|
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
|
||||||
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
|
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
|
||||||
@ -263,8 +275,7 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
|
|||||||
#if MICROPY_SSL_AXTLS
|
#if MICROPY_SSL_AXTLS
|
||||||
STATIC mp_obj_t uhashlib_md5_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 uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
MD5_Init((MD5_CTX *)o->state);
|
MD5_Init((MD5_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -303,8 +314,7 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_md5_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 uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_md5_init((mbedtls_md5_context *)o->state);
|
mbedtls_md5_init((mbedtls_md5_context *)o->state);
|
||||||
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
|
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
|
||||||
@ -372,4 +382,6 @@ const mp_obj_module_t mp_module_uhashlib = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_hashlib, mp_module_uhashlib);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UHASHLIB
|
#endif // MICROPY_PY_UHASHLIB
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 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 "py/objlist.h"
|
#include "py/objlist.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
@ -98,6 +119,8 @@ const mp_obj_module_t mp_module_uheapq = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_heapq, mp_module_uheapq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_PY_UHEAPQ
|
#endif // MICROPY_PY_UHEAPQ
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2019 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 <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -112,6 +133,7 @@ typedef struct _ujson_stream_t {
|
|||||||
mp_obj_t stream_obj;
|
mp_obj_t stream_obj;
|
||||||
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
||||||
int errcode;
|
int errcode;
|
||||||
|
// CIRCUITPY
|
||||||
mp_obj_t python_readinto[2 + 1];
|
mp_obj_t python_readinto[2 + 1];
|
||||||
mp_obj_array_t bytearray_obj;
|
mp_obj_array_t bytearray_obj;
|
||||||
size_t start;
|
size_t start;
|
||||||
@ -136,6 +158,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
|
|||||||
return s->cur;
|
return s->cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CIRCUITPY
|
||||||
|
|
||||||
// We read from an object's `readinto` method in chunks larger than the json
|
// We read from an object's `readinto` method in chunks larger than the json
|
||||||
// parser needs to reduce the number of function calls done.
|
// parser needs to reduce the number of function calls done.
|
||||||
|
|
||||||
@ -375,6 +399,8 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
success:
|
success:
|
||||||
|
// CIRCUITPY
|
||||||
|
|
||||||
// It is legal for a stream to have contents after JSON.
|
// It is legal for a stream to have contents after JSON.
|
||||||
// E.g., A UART is not closed after receiving an object; in load() we will
|
// E.g., A UART is not closed after receiving an object; in load() we will
|
||||||
// return the first complete JSON object, while in loads() we will retain
|
// return the first complete JSON object, while in loads() we will retain
|
||||||
@ -432,6 +458,6 @@ const mp_obj_module_t mp_module_ujson = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson, MICROPY_PY_UJSON);
|
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UJSON
|
#endif // MICROPY_PY_UJSON
|
||||||
|
186
extmod/moduos.c
Normal file
186
extmod/moduos.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2022 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 "py/objstr.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS
|
||||||
|
|
||||||
|
#include "extmod/misc.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2
|
||||||
|
#include "extmod/vfs_lfs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS_POSIX
|
||||||
|
#include "extmod/vfs_posix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
#include "genhdr/mpversion.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROPY_PY_UOS_INCLUDEFILE
|
||||||
|
#include MICROPY_PY_UOS_INCLUDEFILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROPY_BUILD_TYPE
|
||||||
|
#define MICROPY_BUILD_TYPE_PAREN " (" MICROPY_BUILD_TYPE ")"
|
||||||
|
#else
|
||||||
|
#define MICROPY_BUILD_TYPE_PAREN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC
|
||||||
|
#define CONST_RELEASE
|
||||||
|
#else
|
||||||
|
#define CONST_RELEASE const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC const qstr mp_uos_uname_info_fields[] = {
|
||||||
|
MP_QSTR_sysname,
|
||||||
|
MP_QSTR_nodename,
|
||||||
|
MP_QSTR_release,
|
||||||
|
MP_QSTR_version,
|
||||||
|
MP_QSTR_machine
|
||||||
|
};
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
|
||||||
|
STATIC CONST_RELEASE MP_DEFINE_STR_OBJ(mp_uos_uname_info_release_obj, MICROPY_VERSION_STRING);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE MICROPY_BUILD_TYPE_PAREN);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_ATTRTUPLE(
|
||||||
|
mp_uos_uname_info_obj,
|
||||||
|
mp_uos_uname_info_fields,
|
||||||
|
5,
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_sysname_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_nodename_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_release_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_version_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_machine_obj)
|
||||||
|
);
|
||||||
|
|
||||||
|
STATIC mp_obj_t mp_uos_uname(void) {
|
||||||
|
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC
|
||||||
|
const char *release = mp_uos_uname_release();
|
||||||
|
mp_uos_uname_info_release_obj.len = strlen(release);
|
||||||
|
mp_uos_uname_info_release_obj.data = (const byte *)release;
|
||||||
|
#endif
|
||||||
|
return MP_OBJ_FROM_PTR(&mp_uos_uname_info_obj);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_uos_uname_obj, mp_uos_uname);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mp_uos_getenv_obj) },
|
||||||
|
#if defined(MICROPY_UNIX_COVERAGE)
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mp_uos_getenv_int_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mp_uos_getenv_str_obj) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_uos_putenv_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_uos_unsetenv_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SEP
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SYNC
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_uos_sync_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SYSTEM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mp_uos_system_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&mp_uos_uname_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_URANDOM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_uos_urandom_obj) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The following are MicroPython extensions.
|
||||||
|
|
||||||
|
#if MICROPY_PY_OS_DUPTERM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_DUPTERM_NOTIFY
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&mp_uos_dupterm_notify_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_ERRNO
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_uos_errno_obj) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_LFS1
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_LFS2
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_POSIX
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) },
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t mp_module_uos = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t *)&os_module_globals,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_os, mp_module_uos);
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_UOS
|
@ -29,87 +29,19 @@
|
|||||||
#include "py/objtuple.h"
|
#include "py/objtuple.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/moduplatform.h"
|
||||||
#include "genhdr/mpversion.h"
|
#include "genhdr/mpversion.h"
|
||||||
|
|
||||||
#if MICROPY_PY_UPLATFORM
|
#if MICROPY_PY_UPLATFORM
|
||||||
|
|
||||||
// platform - Access to underlying platform's identifying data
|
// platform - Access to underlying platform's identifying data
|
||||||
|
|
||||||
// TODO: Add more architectures, compilers and libraries.
|
STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, MICROPY_PLATFORM_SYSTEM "-" \
|
||||||
// See: https://sourceforge.net/p/predef/wiki/Home/
|
MICROPY_VERSION_STRING "-" MICROPY_PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" \
|
||||||
|
MICROPY_PLATFORM_LIBC_LIB "" MICROPY_PLATFORM_LIBC_VER);
|
||||||
#if defined(__ARM_ARCH)
|
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, MICROPY_PLATFORM_COMPILER);
|
||||||
#define PLATFORM_ARCH "arm"
|
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, MICROPY_PLATFORM_LIBC_LIB);
|
||||||
#elif defined(__x86_64__) || defined(_WIN64)
|
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, MICROPY_PLATFORM_LIBC_VER);
|
||||||
#define PLATFORM_ARCH "x86_64"
|
|
||||||
#elif defined(__i386__) || defined(_M_IX86)
|
|
||||||
#define PLATFORM_ARCH "x86"
|
|
||||||
#elif defined(__xtensa__) || defined(_M_IX86)
|
|
||||||
#define PLATFORM_ARCH "xtensa"
|
|
||||||
#else
|
|
||||||
#define PLATFORM_ARCH ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"GCC " \
|
|
||||||
MP_STRINGIFY(__GNUC__) "." \
|
|
||||||
MP_STRINGIFY(__GNUC_MINOR__) "." \
|
|
||||||
MP_STRINGIFY(__GNUC_PATCHLEVEL__)
|
|
||||||
#elif defined(__ARMCC_VERSION)
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"ARMCC " \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION % 10000))
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#if defined(_WIN64)
|
|
||||||
#define COMPILER_BITS "64 bit"
|
|
||||||
#elif defined(_M_IX86)
|
|
||||||
#define COMPILER_BITS "32 bit"
|
|
||||||
#else
|
|
||||||
#define COMPILER_BITS ""
|
|
||||||
#endif
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"MSC v." MP_STRINGIFY(_MSC_VER) " " COMPILER_BITS
|
|
||||||
#else
|
|
||||||
#define PLATFORM_COMPILER ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GLIBC__)
|
|
||||||
#define PLATFORM_LIBC_LIB "glibc"
|
|
||||||
#define PLATFORM_LIBC_VER \
|
|
||||||
MP_STRINGIFY(__GLIBC__) "." \
|
|
||||||
MP_STRINGIFY(__GLIBC_MINOR__)
|
|
||||||
#elif defined(__NEWLIB__)
|
|
||||||
#define PLATFORM_LIBC_LIB "newlib"
|
|
||||||
#define PLATFORM_LIBC_VER _NEWLIB_VERSION
|
|
||||||
#else
|
|
||||||
#define PLATFORM_LIBC_LIB ""
|
|
||||||
#define PLATFORM_LIBC_VER ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__linux)
|
|
||||||
#define PLATFORM_SYSTEM "Linux"
|
|
||||||
#elif defined(__unix__)
|
|
||||||
#define PLATFORM_SYSTEM "Unix"
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
#define PLATFORM_SYSTEM "Cygwin"
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
#define PLATFORM_SYSTEM "Windows"
|
|
||||||
#else
|
|
||||||
#define PLATFORM_SYSTEM "MicroPython"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MICROPY_PLATFORM_VERSION
|
|
||||||
#define MICROPY_PLATFORM_VERSION ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-" \
|
|
||||||
PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER);
|
|
||||||
STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = {
|
STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = {
|
||||||
{&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)}
|
{&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)}
|
||||||
};
|
};
|
||||||
@ -143,4 +75,6 @@ const mp_obj_module_t mp_module_uplatform = {
|
|||||||
.globals = (mp_obj_dict_t *)&modplatform_globals,
|
.globals = (mp_obj_dict_t *)&modplatform_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_platform, mp_module_uplatform);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UPLATFORM
|
#endif // MICROPY_PY_UPLATFORM
|
||||||
|
105
extmod/moduplatform.h
Normal file
105
extmod/moduplatform.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||||
|
*
|
||||||
|
* 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_MODUPLATFORM_H
|
||||||
|
#define MICROPY_INCLUDED_MODUPLATFORM_H
|
||||||
|
|
||||||
|
#include "py/misc.h" // For MP_STRINGIFY.
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
|
||||||
|
// Preprocessor directives identifying the platform.
|
||||||
|
// The (u)platform module itself is guarded by MICROPY_PY_UPLATFORM, see the
|
||||||
|
// .c file, but these are made available because they're generally usable.
|
||||||
|
// TODO: Add more architectures, compilers and libraries.
|
||||||
|
// See: https://sourceforge.net/p/predef/wiki/Home/
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "arm"
|
||||||
|
#elif defined(__x86_64__) || defined(_WIN64)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "x86_64"
|
||||||
|
#elif defined(__i386__) || defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "x86"
|
||||||
|
#elif defined(__xtensa__) || defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "xtensa"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_ARCH ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"GCC " \
|
||||||
|
MP_STRINGIFY(__GNUC__) "." \
|
||||||
|
MP_STRINGIFY(__GNUC_MINOR__) "." \
|
||||||
|
MP_STRINGIFY(__GNUC_PATCHLEVEL__)
|
||||||
|
#elif defined(__ARMCC_VERSION)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"ARMCC " \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION % 10000))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS "64 bit"
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS "32 bit"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS ""
|
||||||
|
#endif
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"MSC v." MP_STRINGIFY(_MSC_VER) " " MICROPY_PLATFORM_COMPILER_BITS
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_COMPILER ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GLIBC__)
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB "glibc"
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER \
|
||||||
|
MP_STRINGIFY(__GLIBC__) "." \
|
||||||
|
MP_STRINGIFY(__GLIBC_MINOR__)
|
||||||
|
#elif defined(__NEWLIB__)
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB "newlib"
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB ""
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Linux"
|
||||||
|
#elif defined(__unix__)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Unix"
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Cygwin"
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Windows"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "MicroPython"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MICROPY_PLATFORM_VERSION
|
||||||
|
#define MICROPY_PLATFORM_VERSION ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_MODUPLATFORM_H
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -195,7 +216,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform);
|
|||||||
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
|
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
|
||||||
|
|
||||||
#if SEED_ON_IMPORT
|
#if SEED_ON_IMPORT
|
||||||
STATIC mp_obj_t mod_urandom___init__() {
|
STATIC mp_obj_t mod_urandom___init__(void) {
|
||||||
// This module may be imported by more than one name so need to ensure
|
// This module may be imported by more than one name so need to ensure
|
||||||
// that it's only ever seeded once.
|
// that it's only ever seeded once.
|
||||||
static bool seeded = false;
|
static bool seeded = false;
|
||||||
@ -233,6 +254,8 @@ const mp_obj_module_t mp_module_urandom = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_random, mp_module_urandom);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_PY_URANDOM
|
#endif // MICROPY_PY_URANDOM
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -18,6 +39,7 @@
|
|||||||
|
|
||||||
#include "lib/re1.5/re1.5.h"
|
#include "lib/re1.5/re1.5.h"
|
||||||
|
|
||||||
|
// CIRCUITPY
|
||||||
#if MICROPY_PY_URE_DEBUG
|
#if MICROPY_PY_URE_DEBUG
|
||||||
#define FLAG_DEBUG 0x1000
|
#define FLAG_DEBUG 0x1000
|
||||||
#endif
|
#endif
|
||||||
@ -168,7 +190,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
Subject subj;
|
Subject subj;
|
||||||
size_t len;
|
size_t len;
|
||||||
subj.begin = mp_obj_str_get_data(args[1], &len);
|
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
||||||
subj.end = subj.begin + len;
|
subj.end = subj.begin + len;
|
||||||
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
||||||
|
|
||||||
@ -231,7 +253,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
|
|||||||
Subject subj;
|
Subject subj;
|
||||||
size_t len;
|
size_t len;
|
||||||
const mp_obj_type_t *str_type = mp_obj_get_type(args[1]);
|
const mp_obj_type_t *str_type = mp_obj_get_type(args[1]);
|
||||||
subj.begin = mp_obj_str_get_data(args[1], &len);
|
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
||||||
subj.end = subj.begin + len;
|
subj.end = subj.begin + len;
|
||||||
int caps_num = (self->re.sub + 1) * 2;
|
int caps_num = (self->re.sub + 1) * 2;
|
||||||
|
|
||||||
@ -291,7 +313,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
|
|||||||
size_t where_len;
|
size_t where_len;
|
||||||
const char *where_str = mp_obj_str_get_data(where, &where_len);
|
const char *where_str = mp_obj_str_get_data(where, &where_len);
|
||||||
Subject subj;
|
Subject subj;
|
||||||
subj.begin = where_str;
|
subj.begin_line = subj.begin = where_str;
|
||||||
subj.end = subj.begin + where_len;
|
subj.end = subj.begin + where_len;
|
||||||
int caps_num = (self->re.sub + 1) * 2;
|
int caps_num = (self->re.sub + 1) * 2;
|
||||||
|
|
||||||
@ -421,8 +443,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
|
|||||||
if (size == -1) {
|
if (size == -1) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
|
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type);
|
||||||
o->base.type = &re_type;
|
|
||||||
#if MICROPY_PY_URE_DEBUG
|
#if MICROPY_PY_URE_DEBUG
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (n_args > 1) {
|
if (n_args > 1) {
|
||||||
@ -470,7 +491,7 @@ const mp_obj_module_t mp_module_ure = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_re_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_re_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure, MICROPY_PY_URE);
|
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Source files #include'd here to make sure they're compiled in
|
// Source files #include'd here to make sure they're compiled in
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
* Copyright (c) 2015-2017 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_PY_USELECT
|
#if MICROPY_PY_USELECT
|
||||||
@ -151,6 +172,7 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
|
|||||||
mp_map_deinit(&poll_map);
|
mp_map_deinit(&poll_map);
|
||||||
return mp_obj_new_tuple(3, list_array);
|
return mp_obj_new_tuple(3, list_array);
|
||||||
}
|
}
|
||||||
|
// CIRCUITPY
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,6 +252,7 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
|
|||||||
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
|
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// CIRCUITPY
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
if (mp_hal_is_interrupted()) {
|
if (mp_hal_is_interrupted()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -333,8 +356,7 @@ STATIC const mp_obj_type_t mp_type_poll = {
|
|||||||
|
|
||||||
// poll()
|
// poll()
|
||||||
STATIC mp_obj_t select_poll(void) {
|
STATIC mp_obj_t select_poll(void) {
|
||||||
mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t);
|
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
|
||||||
poll->base.type = &mp_type_poll;
|
|
||||||
mp_map_init(&poll->poll_map, 0);
|
mp_map_init(&poll->poll_map, 0);
|
||||||
poll->iter_cnt = 0;
|
poll->iter_cnt = 0;
|
||||||
poll->ret_tuple = MP_OBJ_NULL;
|
poll->ret_tuple = MP_OBJ_NULL;
|
||||||
@ -361,6 +383,6 @@ const mp_obj_module_t mp_module_uselect = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect, MICROPY_PY_USELECT);
|
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect);
|
||||||
|
|
||||||
#endif // MICROPY_PY_USELECT
|
#endif // MICROPY_PY_USELECT
|
||||||
|
@ -1,217 +0,0 @@
|
|||||||
// Copyright (c) 2016-2017 Paul Sokolovsky
|
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/objlist.h"
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/smallint.h"
|
|
||||||
|
|
||||||
#include "supervisor/shared/translate/translate.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_UTIMEQ
|
|
||||||
|
|
||||||
#define MODULO MICROPY_PY_UTIME_TICKS_PERIOD
|
|
||||||
|
|
||||||
#define DEBUG 0
|
|
||||||
|
|
||||||
// the algorithm here is modelled on CPython's heapq.py
|
|
||||||
|
|
||||||
struct qentry {
|
|
||||||
mp_uint_t time;
|
|
||||||
mp_uint_t id;
|
|
||||||
mp_obj_t callback;
|
|
||||||
mp_obj_t args;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _mp_obj_utimeq_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
mp_uint_t alloc;
|
|
||||||
mp_uint_t len;
|
|
||||||
struct qentry items[];
|
|
||||||
} mp_obj_utimeq_t;
|
|
||||||
|
|
||||||
STATIC mp_uint_t utimeq_id;
|
|
||||||
|
|
||||||
STATIC mp_obj_utimeq_t *utimeq_get_heap(mp_obj_t heap_in) {
|
|
||||||
return MP_OBJ_TO_PTR(heap_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC bool time_less_than(struct qentry *item, struct qentry *parent) {
|
|
||||||
mp_uint_t item_tm = item->time;
|
|
||||||
mp_uint_t parent_tm = parent->time;
|
|
||||||
mp_uint_t res = parent_tm - item_tm;
|
|
||||||
if (res == 0) {
|
|
||||||
// TODO: This actually should use the same "ring" logic
|
|
||||||
// as for time, to avoid artifacts when id's overflow.
|
|
||||||
return item->id < parent->id;
|
|
||||||
}
|
|
||||||
if ((mp_int_t)res < 0) {
|
|
||||||
res += MODULO;
|
|
||||||
}
|
|
||||||
return res && res < (MODULO / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t utimeq_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, 1, false);
|
|
||||||
mp_uint_t alloc = mp_obj_get_int(args[0]);
|
|
||||||
mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc);
|
|
||||||
o->base.type = type;
|
|
||||||
memset(o->items, 0, sizeof(*o->items) * alloc);
|
|
||||||
o->alloc = alloc;
|
|
||||||
o->len = 0;
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void utimeq_heap_siftdown(mp_obj_utimeq_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
|
|
||||||
struct qentry item = heap->items[pos];
|
|
||||||
while (pos > start_pos) {
|
|
||||||
mp_uint_t parent_pos = (pos - 1) >> 1;
|
|
||||||
struct qentry *parent = &heap->items[parent_pos];
|
|
||||||
bool lessthan = time_less_than(&item, parent);
|
|
||||||
if (lessthan) {
|
|
||||||
heap->items[pos] = *parent;
|
|
||||||
pos = parent_pos;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
heap->items[pos] = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void utimeq_heap_siftup(mp_obj_utimeq_t *heap, mp_uint_t pos) {
|
|
||||||
mp_uint_t start_pos = pos;
|
|
||||||
mp_uint_t end_pos = heap->len;
|
|
||||||
struct qentry item = heap->items[pos];
|
|
||||||
for (mp_uint_t child_pos = 2 * pos + 1; child_pos < end_pos; child_pos = 2 * pos + 1) {
|
|
||||||
// choose right child if it's <= left child
|
|
||||||
if (child_pos + 1 < end_pos) {
|
|
||||||
bool lessthan = time_less_than(&heap->items[child_pos], &heap->items[child_pos + 1]);
|
|
||||||
if (!lessthan) {
|
|
||||||
child_pos += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// bubble up the smaller child
|
|
||||||
heap->items[pos] = heap->items[child_pos];
|
|
||||||
pos = child_pos;
|
|
||||||
}
|
|
||||||
heap->items[pos] = item;
|
|
||||||
utimeq_heap_siftdown(heap, start_pos, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
mp_obj_t heap_in = args[0];
|
|
||||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
|
||||||
if (heap->len == heap->alloc) {
|
|
||||||
mp_raise_IndexError(MP_ERROR_TEXT("queue overflow"));
|
|
||||||
}
|
|
||||||
mp_uint_t l = heap->len;
|
|
||||||
heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
|
||||||
heap->items[l].id = utimeq_id++;
|
|
||||||
heap->items[l].callback = args[2];
|
|
||||||
heap->items[l].args = args[3];
|
|
||||||
utimeq_heap_siftdown(heap, 0, heap->len);
|
|
||||||
heap->len++;
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_utimeq_heappush);
|
|
||||||
|
|
||||||
STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
|
|
||||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
|
||||||
if (heap->len == 0) {
|
|
||||||
mp_raise_IndexError(MP_ERROR_TEXT("empty heap"));
|
|
||||||
}
|
|
||||||
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
|
|
||||||
if (!mp_obj_is_type(list_ref, &mp_type_list) || ret->len < 3) {
|
|
||||||
mp_raise_TypeError(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct qentry *item = &heap->items[0];
|
|
||||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(item->time);
|
|
||||||
ret->items[1] = item->callback;
|
|
||||||
ret->items[2] = item->args;
|
|
||||||
heap->len -= 1;
|
|
||||||
heap->items[0] = heap->items[heap->len];
|
|
||||||
heap->items[heap->len].callback = MP_OBJ_NULL; // so we don't retain a pointer
|
|
||||||
heap->items[heap->len].args = MP_OBJ_NULL;
|
|
||||||
if (heap->len) {
|
|
||||||
utimeq_heap_siftup(heap, 0);
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop);
|
|
||||||
|
|
||||||
STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) {
|
|
||||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
|
||||||
if (heap->len == 0) {
|
|
||||||
mp_raise_IndexError(MP_ERROR_TEXT("empty heap"));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct qentry *item = &heap->items[0];
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(item->time);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_peektime_obj, mod_utimeq_peektime);
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
STATIC mp_obj_t mod_utimeq_dump(mp_obj_t heap_in) {
|
|
||||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
|
||||||
for (int i = 0; i < heap->len; i++) {
|
|
||||||
printf(UINT_FMT "\t%p\t%p\n", heap->items[i].time,
|
|
||||||
MP_OBJ_TO_PTR(heap->items[i].callback), MP_OBJ_TO_PTR(heap->items[i].args));
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_dump_obj, mod_utimeq_dump);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC mp_obj_t utimeq_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
|
||||||
mp_obj_utimeq_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
switch (op) {
|
|
||||||
case MP_UNARY_OP_BOOL:
|
|
||||||
return mp_obj_new_bool(self->len != 0);
|
|
||||||
case MP_UNARY_OP_LEN:
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(self->len);
|
|
||||||
default:
|
|
||||||
return MP_OBJ_NULL; // op not supported
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t utimeq_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&mod_utimeq_heappush_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&mod_utimeq_heappop_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_peektime), MP_ROM_PTR(&mod_utimeq_peektime_obj) },
|
|
||||||
#if DEBUG
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_utimeq_dump_obj) },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(utimeq_locals_dict, utimeq_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC const mp_obj_type_t utimeq_type = {
|
|
||||||
{ &mp_type_type },
|
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
|
||||||
.name = MP_QSTR_utimeq,
|
|
||||||
.make_new = utimeq_make_new,
|
|
||||||
.locals_dict = (void *)&utimeq_locals_dict,
|
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
|
||||||
.unary_op = utimeq_unary_op,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utimeq) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_utimeq), MP_ROM_PTR(&utimeq_type) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(mp_module_utimeq_globals, mp_module_utimeq_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_utimeq = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_utimeq_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_UTIMEQ
|
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014-2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -51,15 +72,14 @@ STATIC int read_src_stream(TINF_DATA *data) {
|
|||||||
STATIC mp_obj_t decompio_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 decompio_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, 2, false);
|
mp_arg_check_num(n_args, n_kw, 1, 2, false);
|
||||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
|
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
|
||||||
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
|
mp_obj_decompio_t *o = mp_obj_malloc(mp_obj_decompio_t, type);
|
||||||
o->base.type = type;
|
|
||||||
memset(&o->decomp, 0, sizeof(o->decomp));
|
memset(&o->decomp, 0, sizeof(o->decomp));
|
||||||
o->decomp.readSource = read_src_stream;
|
o->decomp.readSource = read_src_stream;
|
||||||
o->src_stream = args[0];
|
o->src_stream = args[0];
|
||||||
o->eof = false;
|
o->eof = false;
|
||||||
|
|
||||||
mp_int_t dict_opt = 0;
|
mp_int_t dict_opt = 0;
|
||||||
int dict_sz;
|
uint dict_sz;
|
||||||
if (n_args > 1) {
|
if (n_args > 1) {
|
||||||
dict_opt = mp_obj_get_int(args[1]);
|
dict_opt = mp_obj_get_int(args[1]);
|
||||||
}
|
}
|
||||||
@ -76,7 +96,10 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
header_error:
|
header_error:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
|
mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
|
||||||
}
|
}
|
||||||
dict_sz = 1 << dict_opt;
|
// RFC 1950 section 2.2:
|
||||||
|
// CINFO is the base-2 logarithm of the LZ77 window size,
|
||||||
|
// minus eight (CINFO=7 indicates a 32K window size)
|
||||||
|
dict_sz = 1 << (dict_opt + 8);
|
||||||
} else {
|
} else {
|
||||||
dict_sz = 1 << -dict_opt;
|
dict_sz = 1 << -dict_opt;
|
||||||
}
|
}
|
||||||
@ -92,12 +115,13 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
|
|||||||
}
|
}
|
||||||
|
|
||||||
o->decomp.dest = buf;
|
o->decomp.dest = buf;
|
||||||
o->decomp.dest_limit = (unsigned char *)buf + size;
|
o->decomp.dest_limit = (byte *)buf + size;
|
||||||
int st = uzlib_uncompress_chksum(&o->decomp);
|
int st = uzlib_uncompress_chksum(&o->decomp);
|
||||||
if (st == TINF_DONE) {
|
if (st == TINF_DONE) {
|
||||||
o->eof = true;
|
o->eof = true;
|
||||||
}
|
}
|
||||||
if (st < 0) {
|
if (st < 0) {
|
||||||
|
DEBUG_printf("uncompress error=" INT_FMT "\n", st);
|
||||||
*errcode = MP_EINVAL;
|
*errcode = MP_EINVAL;
|
||||||
return MP_STREAM_ERROR;
|
return MP_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
@ -146,9 +170,10 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
decomp->dest = dest_buf;
|
decomp->dest = dest_buf;
|
||||||
decomp->dest_limit = dest_buf + dest_buf_size;
|
decomp->dest_limit = dest_buf + dest_buf_size;
|
||||||
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize);
|
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", dest_buf_size);
|
||||||
decomp->source = bufinfo.buf;
|
decomp->source = bufinfo.buf;
|
||||||
decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len;
|
decomp->source_limit = (byte *)bufinfo.buf + bufinfo.len;
|
||||||
|
|
||||||
int st;
|
int st;
|
||||||
bool is_zlib = true;
|
bool is_zlib = true;
|
||||||
|
|
||||||
@ -175,7 +200,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
|
|||||||
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
|
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
|
||||||
dest_buf_size += 256;
|
dest_buf_size += 256;
|
||||||
decomp->dest = dest_buf + offset;
|
decomp->dest = dest_buf + offset;
|
||||||
decomp->dest_limit = dest_buf + offset + 256;
|
decomp->dest_limit = decomp->dest + 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_uint_t final_sz = decomp->dest - dest_buf;
|
mp_uint_t final_sz = decomp->dest - dest_buf;
|
||||||
@ -203,6 +228,9 @@ const mp_obj_module_t mp_module_uzlib = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_zlib, mp_module_uzlib);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Source files #include'd here to make sure they're compiled in
|
// Source files #include'd here to make sure they're compiled in
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019 Damien P. George
|
|
||||||
|
|
||||||
from .core import *
|
|
||||||
|
|
||||||
__version__ = (3, 0, 0)
|
|
||||||
|
|
||||||
_attrs = {
|
|
||||||
"wait_for": "funcs",
|
|
||||||
"wait_for_ms": "funcs",
|
|
||||||
"gather": "funcs",
|
|
||||||
"Event": "event",
|
|
||||||
"ThreadSafeFlag": "event",
|
|
||||||
"Lock": "lock",
|
|
||||||
"open_connection": "stream",
|
|
||||||
"start_server": "stream",
|
|
||||||
"StreamReader": "stream",
|
|
||||||
"StreamWriter": "stream",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Lazy loader, effectively does:
|
|
||||||
# global attr
|
|
||||||
# from .mod import attr
|
|
||||||
def __getattr__(attr):
|
|
||||||
mod = _attrs.get(attr, None)
|
|
||||||
if mod is None:
|
|
||||||
raise AttributeError(attr)
|
|
||||||
value = getattr(__import__(mod, None, None, True, 1), attr)
|
|
||||||
globals()[attr] = value
|
|
||||||
return value
|
|
@ -1,295 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019 Damien P. George
|
|
||||||
|
|
||||||
from time import ticks_ms as ticks, ticks_diff, ticks_add
|
|
||||||
import sys, select
|
|
||||||
|
|
||||||
# Import TaskQueue and Task, preferring built-in C code over Python code
|
|
||||||
try:
|
|
||||||
from _uasyncio import TaskQueue, Task
|
|
||||||
except:
|
|
||||||
from .task import TaskQueue, Task
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Exceptions
|
|
||||||
|
|
||||||
|
|
||||||
class CancelledError(BaseException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TimeoutError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Used when calling Loop.call_exception_handler
|
|
||||||
_exc_context = {"message": "Task exception wasn't retrieved", "exception": None, "future": None}
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Sleep functions
|
|
||||||
|
|
||||||
# "Yield" once, then raise StopIteration
|
|
||||||
class SingletonGenerator:
|
|
||||||
def __init__(self):
|
|
||||||
self.state = None
|
|
||||||
self.exc = StopIteration()
|
|
||||||
|
|
||||||
def __await__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
if self.state is not None:
|
|
||||||
_task_queue.push_sorted(cur_task, self.state)
|
|
||||||
self.state = None
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
self.exc.__traceback__ = None
|
|
||||||
raise self.exc
|
|
||||||
|
|
||||||
|
|
||||||
# Pause task execution for the given time (integer in milliseconds, uPy extension)
|
|
||||||
# Use a SingletonGenerator to do it without allocating on the heap
|
|
||||||
def sleep_ms(t, sgen=SingletonGenerator()):
|
|
||||||
assert sgen.state is None
|
|
||||||
sgen.state = ticks_add(ticks(), max(0, t))
|
|
||||||
return sgen
|
|
||||||
|
|
||||||
|
|
||||||
# Pause task execution for the given time (in seconds)
|
|
||||||
def sleep(t):
|
|
||||||
return sleep_ms(int(t * 1000))
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Queue and poller for stream IO
|
|
||||||
|
|
||||||
|
|
||||||
class IOQueue:
|
|
||||||
def __init__(self):
|
|
||||||
self.poller = select.poll()
|
|
||||||
self.map = {} # maps id(stream) to [task_waiting_read, task_waiting_write, stream]
|
|
||||||
|
|
||||||
def _enqueue(self, s, idx):
|
|
||||||
if id(s) not in self.map:
|
|
||||||
entry = [None, None, s]
|
|
||||||
entry[idx] = cur_task
|
|
||||||
self.map[id(s)] = entry
|
|
||||||
self.poller.register(s, select.POLLIN if idx == 0 else select.POLLOUT)
|
|
||||||
else:
|
|
||||||
sm = self.map[id(s)]
|
|
||||||
assert sm[idx] is None
|
|
||||||
assert sm[1 - idx] is not None
|
|
||||||
sm[idx] = cur_task
|
|
||||||
self.poller.modify(s, select.POLLIN | select.POLLOUT)
|
|
||||||
# Link task to this IOQueue so it can be removed if needed
|
|
||||||
cur_task.data = self
|
|
||||||
|
|
||||||
def _dequeue(self, s):
|
|
||||||
del self.map[id(s)]
|
|
||||||
self.poller.unregister(s)
|
|
||||||
|
|
||||||
def queue_read(self, s):
|
|
||||||
self._enqueue(s, 0)
|
|
||||||
|
|
||||||
def queue_write(self, s):
|
|
||||||
self._enqueue(s, 1)
|
|
||||||
|
|
||||||
def remove(self, task):
|
|
||||||
while True:
|
|
||||||
del_s = None
|
|
||||||
for k in self.map: # Iterate without allocating on the heap
|
|
||||||
q0, q1, s = self.map[k]
|
|
||||||
if q0 is task or q1 is task:
|
|
||||||
del_s = s
|
|
||||||
break
|
|
||||||
if del_s is not None:
|
|
||||||
self._dequeue(s)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
def wait_io_event(self, dt):
|
|
||||||
for s, ev in self.poller.ipoll(dt):
|
|
||||||
sm = self.map[id(s)]
|
|
||||||
# print('poll', s, sm, ev)
|
|
||||||
if ev & ~select.POLLOUT and sm[0] is not None:
|
|
||||||
# POLLIN or error
|
|
||||||
_task_queue.push_head(sm[0])
|
|
||||||
sm[0] = None
|
|
||||||
if ev & ~select.POLLIN and sm[1] is not None:
|
|
||||||
# POLLOUT or error
|
|
||||||
_task_queue.push_head(sm[1])
|
|
||||||
sm[1] = None
|
|
||||||
if sm[0] is None and sm[1] is None:
|
|
||||||
self._dequeue(s)
|
|
||||||
elif sm[0] is None:
|
|
||||||
self.poller.modify(s, select.POLLOUT)
|
|
||||||
else:
|
|
||||||
self.poller.modify(s, select.POLLIN)
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Main run loop
|
|
||||||
|
|
||||||
# Ensure the awaitable is a task
|
|
||||||
def _promote_to_task(aw):
|
|
||||||
return aw if isinstance(aw, Task) else create_task(aw)
|
|
||||||
|
|
||||||
|
|
||||||
# Create and schedule a new task from a coroutine
|
|
||||||
def create_task(coro):
|
|
||||||
if not hasattr(coro, "send"):
|
|
||||||
raise TypeError("coroutine expected")
|
|
||||||
t = Task(coro, globals())
|
|
||||||
_task_queue.push_head(t)
|
|
||||||
return t
|
|
||||||
|
|
||||||
|
|
||||||
# Keep scheduling tasks until there are none left to schedule
|
|
||||||
def run_until_complete(main_task=None):
|
|
||||||
global cur_task
|
|
||||||
excs_all = (CancelledError, Exception) # To prevent heap allocation in loop
|
|
||||||
excs_stop = (CancelledError, StopIteration) # To prevent heap allocation in loop
|
|
||||||
while True:
|
|
||||||
# Wait until the head of _task_queue is ready to run
|
|
||||||
dt = 1
|
|
||||||
while dt > 0:
|
|
||||||
dt = -1
|
|
||||||
t = _task_queue.peek()
|
|
||||||
if t:
|
|
||||||
# A task waiting on _task_queue; "ph_key" is time to schedule task at
|
|
||||||
dt = max(0, ticks_diff(t.ph_key, ticks()))
|
|
||||||
elif not _io_queue.map:
|
|
||||||
# No tasks can be woken so finished running
|
|
||||||
return
|
|
||||||
# print('(poll {})'.format(dt), len(_io_queue.map))
|
|
||||||
_io_queue.wait_io_event(dt)
|
|
||||||
|
|
||||||
# Get next task to run and continue it
|
|
||||||
t = _task_queue.pop_head()
|
|
||||||
cur_task = t
|
|
||||||
try:
|
|
||||||
# Continue running the coroutine, it's responsible for rescheduling itself
|
|
||||||
exc = t.data
|
|
||||||
if not exc:
|
|
||||||
t.coro.send(None)
|
|
||||||
else:
|
|
||||||
# If the task is finished and on the run queue and gets here, then it
|
|
||||||
# had an exception and was not await'ed on. Throwing into it now will
|
|
||||||
# raise StopIteration and the code below will catch this and run the
|
|
||||||
# call_exception_handler function.
|
|
||||||
t.data = None
|
|
||||||
t.coro.throw(exc)
|
|
||||||
except excs_all as er:
|
|
||||||
# Check the task is not on any event queue
|
|
||||||
assert t.data is None
|
|
||||||
# This task is done, check if it's the main task and then loop should stop
|
|
||||||
if t is main_task:
|
|
||||||
if isinstance(er, StopIteration):
|
|
||||||
return er.value
|
|
||||||
raise er
|
|
||||||
if t.state:
|
|
||||||
# Task was running but is now finished.
|
|
||||||
waiting = False
|
|
||||||
if t.state is True:
|
|
||||||
# "None" indicates that the task is complete and not await'ed on (yet).
|
|
||||||
t.state = None
|
|
||||||
else:
|
|
||||||
# Schedule any other tasks waiting on the completion of this task.
|
|
||||||
while t.state.peek():
|
|
||||||
_task_queue.push_head(t.state.pop_head())
|
|
||||||
waiting = True
|
|
||||||
# "False" indicates that the task is complete and has been await'ed on.
|
|
||||||
t.state = False
|
|
||||||
if not waiting and not isinstance(er, excs_stop):
|
|
||||||
# An exception ended this detached task, so queue it for later
|
|
||||||
# execution to handle the uncaught exception if no other task retrieves
|
|
||||||
# the exception in the meantime (this is handled by Task.throw).
|
|
||||||
_task_queue.push_head(t)
|
|
||||||
# Save return value of coro to pass up to caller.
|
|
||||||
t.data = er
|
|
||||||
elif t.state is None:
|
|
||||||
# Task is already finished and nothing await'ed on the task,
|
|
||||||
# so call the exception handler.
|
|
||||||
_exc_context["exception"] = exc
|
|
||||||
_exc_context["future"] = t
|
|
||||||
Loop.call_exception_handler(_exc_context)
|
|
||||||
|
|
||||||
|
|
||||||
# Create a new task from a coroutine and run it until it finishes
|
|
||||||
def run(coro):
|
|
||||||
return run_until_complete(create_task(coro))
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Event loop wrapper
|
|
||||||
|
|
||||||
|
|
||||||
async def _stopper():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
_stop_task = None
|
|
||||||
|
|
||||||
|
|
||||||
class Loop:
|
|
||||||
_exc_handler = None
|
|
||||||
|
|
||||||
def create_task(coro):
|
|
||||||
return create_task(coro)
|
|
||||||
|
|
||||||
def run_forever():
|
|
||||||
global _stop_task
|
|
||||||
_stop_task = Task(_stopper(), globals())
|
|
||||||
run_until_complete(_stop_task)
|
|
||||||
# TODO should keep running until .stop() is called, even if there're no tasks left
|
|
||||||
|
|
||||||
def run_until_complete(aw):
|
|
||||||
return run_until_complete(_promote_to_task(aw))
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
global _stop_task
|
|
||||||
if _stop_task is not None:
|
|
||||||
_task_queue.push_head(_stop_task)
|
|
||||||
# If stop() is called again, do nothing
|
|
||||||
_stop_task = None
|
|
||||||
|
|
||||||
def close():
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_exception_handler(handler):
|
|
||||||
Loop._exc_handler = handler
|
|
||||||
|
|
||||||
def get_exception_handler():
|
|
||||||
return Loop._exc_handler
|
|
||||||
|
|
||||||
def default_exception_handler(loop, context):
|
|
||||||
print(context["message"])
|
|
||||||
print("future:", context["future"], "coro=", context["future"].coro)
|
|
||||||
sys.print_exception(context["exception"])
|
|
||||||
|
|
||||||
def call_exception_handler(context):
|
|
||||||
(Loop._exc_handler or Loop.default_exception_handler)(Loop, context)
|
|
||||||
|
|
||||||
|
|
||||||
# The runq_len and waitq_len arguments are for legacy uasyncio compatibility
|
|
||||||
def get_event_loop(runq_len=0, waitq_len=0):
|
|
||||||
return Loop
|
|
||||||
|
|
||||||
|
|
||||||
def current_task():
|
|
||||||
return cur_task
|
|
||||||
|
|
||||||
|
|
||||||
def new_event_loop():
|
|
||||||
global _task_queue, _io_queue
|
|
||||||
# TaskQueue of Task instances
|
|
||||||
_task_queue = TaskQueue()
|
|
||||||
# Task queue and poller for stream IO
|
|
||||||
_io_queue = IOQueue()
|
|
||||||
return Loop
|
|
||||||
|
|
||||||
|
|
||||||
# Initialise default event loop
|
|
||||||
new_event_loop()
|
|
@ -1,33 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
# Event class for primitive events that can be waited on, set, and cleared
|
|
||||||
class Event:
|
|
||||||
def __init__(self):
|
|
||||||
self.state = False # False=unset; True=set
|
|
||||||
self.waiting = core.TaskQueue() # Queue of Tasks waiting on completion of this event
|
|
||||||
|
|
||||||
def is_set(self):
|
|
||||||
return self.state
|
|
||||||
|
|
||||||
def set(self):
|
|
||||||
# Event becomes set, schedule any tasks waiting on it
|
|
||||||
# Note: This must not be called from anything except the thread running
|
|
||||||
# the asyncio loop (i.e. neither hard or soft IRQ, or a different thread).
|
|
||||||
while self.waiting.peek():
|
|
||||||
core._task_queue.push_head(self.waiting.pop_head())
|
|
||||||
self.state = True
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
self.state = False
|
|
||||||
|
|
||||||
async def wait(self):
|
|
||||||
if not self.state:
|
|
||||||
# Event not set, put the calling task on the event's waiting queue
|
|
||||||
self.waiting.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to the event's queue so it can be removed if needed
|
|
||||||
core.cur_task.data = self.waiting
|
|
||||||
yield
|
|
||||||
return True
|
|
@ -1,74 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
async def wait_for(aw, timeout, sleep=core.sleep):
|
|
||||||
aw = core._promote_to_task(aw)
|
|
||||||
if timeout is None:
|
|
||||||
return await aw
|
|
||||||
|
|
||||||
def runner(waiter, aw):
|
|
||||||
nonlocal status, result
|
|
||||||
try:
|
|
||||||
result = await aw
|
|
||||||
s = True
|
|
||||||
except BaseException as er:
|
|
||||||
s = er
|
|
||||||
if status is None:
|
|
||||||
# The waiter is still waiting, set status for it and cancel it.
|
|
||||||
status = s
|
|
||||||
waiter.cancel()
|
|
||||||
|
|
||||||
# Run aw in a separate runner task that manages its exceptions.
|
|
||||||
status = None
|
|
||||||
result = None
|
|
||||||
runner_task = core.create_task(runner(core.cur_task, aw))
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Wait for the timeout to elapse.
|
|
||||||
await sleep(timeout)
|
|
||||||
except core.CancelledError as er:
|
|
||||||
if status is True:
|
|
||||||
# aw completed successfully and cancelled the sleep, so return aw's result.
|
|
||||||
return result
|
|
||||||
elif status is None:
|
|
||||||
# This wait_for was cancelled externally, so cancel aw and re-raise.
|
|
||||||
status = True
|
|
||||||
runner_task.cancel()
|
|
||||||
raise er
|
|
||||||
else:
|
|
||||||
# aw raised an exception, propagate it out to the caller.
|
|
||||||
raise status
|
|
||||||
|
|
||||||
# The sleep finished before aw, so cancel aw and raise TimeoutError.
|
|
||||||
status = True
|
|
||||||
runner_task.cancel()
|
|
||||||
await runner_task
|
|
||||||
raise core.TimeoutError
|
|
||||||
|
|
||||||
|
|
||||||
def wait_for_ms(aw, timeout):
|
|
||||||
return wait_for(aw, timeout, core.sleep_ms)
|
|
||||||
|
|
||||||
|
|
||||||
async def gather(*aws, return_exceptions=False):
|
|
||||||
ts = [core._promote_to_task(aw) for aw in aws]
|
|
||||||
for i in range(len(ts)):
|
|
||||||
try:
|
|
||||||
# TODO handle cancel of gather itself
|
|
||||||
# if ts[i].coro:
|
|
||||||
# iter(ts[i]).waiting.push_head(cur_task)
|
|
||||||
# try:
|
|
||||||
# yield
|
|
||||||
# except CancelledError as er:
|
|
||||||
# # cancel all waiting tasks
|
|
||||||
# raise er
|
|
||||||
ts[i] = await ts[i]
|
|
||||||
except (core.CancelledError, Exception) as er:
|
|
||||||
if return_exceptions:
|
|
||||||
ts[i] = er
|
|
||||||
else:
|
|
||||||
raise er
|
|
||||||
return ts
|
|
@ -1,53 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
# Lock class for primitive mutex capability
|
|
||||||
class Lock:
|
|
||||||
def __init__(self):
|
|
||||||
# The state can take the following values:
|
|
||||||
# - 0: unlocked
|
|
||||||
# - 1: locked
|
|
||||||
# - <Task>: unlocked but this task has been scheduled to acquire the lock next
|
|
||||||
self.state = 0
|
|
||||||
# Queue of Tasks waiting to acquire this Lock
|
|
||||||
self.waiting = core.TaskQueue()
|
|
||||||
|
|
||||||
def locked(self):
|
|
||||||
return self.state == 1
|
|
||||||
|
|
||||||
def release(self):
|
|
||||||
if self.state != 1:
|
|
||||||
raise RuntimeError("Lock not acquired")
|
|
||||||
if self.waiting.peek():
|
|
||||||
# Task(s) waiting on lock, schedule next Task
|
|
||||||
self.state = self.waiting.pop_head()
|
|
||||||
core._task_queue.push_head(self.state)
|
|
||||||
else:
|
|
||||||
# No Task waiting so unlock
|
|
||||||
self.state = 0
|
|
||||||
|
|
||||||
async def acquire(self):
|
|
||||||
if self.state != 0:
|
|
||||||
# Lock unavailable, put the calling Task on the waiting queue
|
|
||||||
self.waiting.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to the lock's queue so it can be removed if needed
|
|
||||||
core.cur_task.data = self.waiting
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except core.CancelledError as er:
|
|
||||||
if self.state == core.cur_task:
|
|
||||||
# Cancelled while pending on resume, schedule next waiting Task
|
|
||||||
self.state = 1
|
|
||||||
self.release()
|
|
||||||
raise er
|
|
||||||
# Lock available, set it as locked
|
|
||||||
self.state = 1
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
return await self.acquire()
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
return self.release()
|
|
@ -1,13 +0,0 @@
|
|||||||
# This list of frozen files doesn't include task.py because that's provided by the C module.
|
|
||||||
freeze(
|
|
||||||
"..",
|
|
||||||
(
|
|
||||||
"uasyncio/__init__.py",
|
|
||||||
"uasyncio/core.py",
|
|
||||||
"uasyncio/event.py",
|
|
||||||
"uasyncio/funcs.py",
|
|
||||||
"uasyncio/lock.py",
|
|
||||||
"uasyncio/stream.py",
|
|
||||||
),
|
|
||||||
opt=3,
|
|
||||||
)
|
|
@ -1,164 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
class Stream:
|
|
||||||
def __init__(self, s, e={}):
|
|
||||||
self.s = s
|
|
||||||
self.e = e
|
|
||||||
self.out_buf = b""
|
|
||||||
|
|
||||||
def get_extra_info(self, v):
|
|
||||||
return self.e[v]
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
await self.close()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def wait_closed(self):
|
|
||||||
# TODO yield?
|
|
||||||
self.s.close()
|
|
||||||
|
|
||||||
async def read(self, n):
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
return self.s.read(n)
|
|
||||||
|
|
||||||
async def readinto(self, buf):
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
return self.s.readinto(buf)
|
|
||||||
|
|
||||||
async def readexactly(self, n):
|
|
||||||
r = b""
|
|
||||||
while n:
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
r2 = self.s.read(n)
|
|
||||||
if r2 is not None:
|
|
||||||
if not len(r2):
|
|
||||||
raise EOFError
|
|
||||||
r += r2
|
|
||||||
n -= len(r2)
|
|
||||||
return r
|
|
||||||
|
|
||||||
async def readline(self):
|
|
||||||
l = b""
|
|
||||||
while True:
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
l2 = self.s.readline() # may do multiple reads but won't block
|
|
||||||
l += l2
|
|
||||||
if not l2 or l[-1] == 10: # \n (check l in case l2 is str)
|
|
||||||
return l
|
|
||||||
|
|
||||||
def write(self, buf):
|
|
||||||
self.out_buf += buf
|
|
||||||
|
|
||||||
async def drain(self):
|
|
||||||
mv = memoryview(self.out_buf)
|
|
||||||
off = 0
|
|
||||||
while off < len(mv):
|
|
||||||
yield core._io_queue.queue_write(self.s)
|
|
||||||
ret = self.s.write(mv[off:])
|
|
||||||
if ret is not None:
|
|
||||||
off += ret
|
|
||||||
self.out_buf = b""
|
|
||||||
|
|
||||||
|
|
||||||
# Stream can be used for both reading and writing to save code size
|
|
||||||
StreamReader = Stream
|
|
||||||
StreamWriter = Stream
|
|
||||||
|
|
||||||
|
|
||||||
# Create a TCP stream connection to a remote host
|
|
||||||
async def open_connection(host, port):
|
|
||||||
from uerrno import EINPROGRESS
|
|
||||||
import usocket as socket
|
|
||||||
|
|
||||||
ai = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0] # TODO this is blocking!
|
|
||||||
s = socket.socket(ai[0], ai[1], ai[2])
|
|
||||||
s.setblocking(False)
|
|
||||||
ss = Stream(s)
|
|
||||||
try:
|
|
||||||
s.connect(ai[-1])
|
|
||||||
except OSError as er:
|
|
||||||
if er.errno != EINPROGRESS:
|
|
||||||
raise er
|
|
||||||
yield core._io_queue.queue_write(s)
|
|
||||||
return ss, ss
|
|
||||||
|
|
||||||
|
|
||||||
# Class representing a TCP stream server, can be closed and used in "async with"
|
|
||||||
class Server:
|
|
||||||
async def __aenter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
self.close()
|
|
||||||
await self.wait_closed()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.task.cancel()
|
|
||||||
|
|
||||||
async def wait_closed(self):
|
|
||||||
await self.task
|
|
||||||
|
|
||||||
async def _serve(self, s, cb):
|
|
||||||
# Accept incoming connections
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
yield core._io_queue.queue_read(s)
|
|
||||||
except core.CancelledError:
|
|
||||||
# Shutdown server
|
|
||||||
s.close()
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
s2, addr = s.accept()
|
|
||||||
except:
|
|
||||||
# Ignore a failed accept
|
|
||||||
continue
|
|
||||||
s2.setblocking(False)
|
|
||||||
s2s = Stream(s2, {"peername": addr})
|
|
||||||
core.create_task(cb(s2s, s2s))
|
|
||||||
|
|
||||||
|
|
||||||
# Helper function to start a TCP stream server, running as a new task
|
|
||||||
# TODO could use an accept-callback on socket read activity instead of creating a task
|
|
||||||
async def start_server(cb, host, port, backlog=5):
|
|
||||||
import usocket as socket
|
|
||||||
|
|
||||||
# Create and bind server socket.
|
|
||||||
host = socket.getaddrinfo(host, port)[0] # TODO this is blocking!
|
|
||||||
s = socket.socket()
|
|
||||||
s.setblocking(False)
|
|
||||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
s.bind(host[-1])
|
|
||||||
s.listen(backlog)
|
|
||||||
|
|
||||||
# Create and return server object and task.
|
|
||||||
srv = Server()
|
|
||||||
srv.task = core.create_task(srv._serve(s, cb))
|
|
||||||
return srv
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Legacy uasyncio compatibility
|
|
||||||
|
|
||||||
|
|
||||||
async def stream_awrite(self, buf, off=0, sz=-1):
|
|
||||||
if off != 0 or sz != -1:
|
|
||||||
buf = memoryview(buf)
|
|
||||||
if sz == -1:
|
|
||||||
sz = len(buf)
|
|
||||||
buf = buf[off : off + sz]
|
|
||||||
self.write(buf)
|
|
||||||
await self.drain()
|
|
||||||
|
|
||||||
|
|
||||||
Stream.aclose = Stream.wait_closed
|
|
||||||
Stream.awrite = stream_awrite
|
|
||||||
Stream.awritestr = stream_awrite # TODO explicitly convert to bytes?
|
|
@ -1,179 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
# This file contains the core TaskQueue based on a pairing heap, and the core Task class.
|
|
||||||
# They can optionally be replaced by C implementations.
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap meld of 2 heaps; O(1)
|
|
||||||
def ph_meld(h1, h2):
|
|
||||||
if h1 is None:
|
|
||||||
return h2
|
|
||||||
if h2 is None:
|
|
||||||
return h1
|
|
||||||
lt = core.ticks_diff(h1.ph_key, h2.ph_key) < 0
|
|
||||||
if lt:
|
|
||||||
if h1.ph_child is None:
|
|
||||||
h1.ph_child = h2
|
|
||||||
else:
|
|
||||||
h1.ph_child_last.ph_next = h2
|
|
||||||
h1.ph_child_last = h2
|
|
||||||
h2.ph_next = None
|
|
||||||
h2.ph_rightmost_parent = h1
|
|
||||||
return h1
|
|
||||||
else:
|
|
||||||
h1.ph_next = h2.ph_child
|
|
||||||
h2.ph_child = h1
|
|
||||||
if h1.ph_next is None:
|
|
||||||
h2.ph_child_last = h1
|
|
||||||
h1.ph_rightmost_parent = h2
|
|
||||||
return h2
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap pairing operation; amortised O(log N)
|
|
||||||
def ph_pairing(child):
|
|
||||||
heap = None
|
|
||||||
while child is not None:
|
|
||||||
n1 = child
|
|
||||||
child = child.ph_next
|
|
||||||
n1.ph_next = None
|
|
||||||
if child is not None:
|
|
||||||
n2 = child
|
|
||||||
child = child.ph_next
|
|
||||||
n2.ph_next = None
|
|
||||||
n1 = ph_meld(n1, n2)
|
|
||||||
heap = ph_meld(heap, n1)
|
|
||||||
return heap
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap delete of a node; stable, amortised O(log N)
|
|
||||||
def ph_delete(heap, node):
|
|
||||||
if node is heap:
|
|
||||||
child = heap.ph_child
|
|
||||||
node.ph_child = None
|
|
||||||
return ph_pairing(child)
|
|
||||||
# Find parent of node
|
|
||||||
parent = node
|
|
||||||
while parent.ph_next is not None:
|
|
||||||
parent = parent.ph_next
|
|
||||||
parent = parent.ph_rightmost_parent
|
|
||||||
# Replace node with pairing of its children
|
|
||||||
if node is parent.ph_child and node.ph_child is None:
|
|
||||||
parent.ph_child = node.ph_next
|
|
||||||
node.ph_next = None
|
|
||||||
return heap
|
|
||||||
elif node is parent.ph_child:
|
|
||||||
child = node.ph_child
|
|
||||||
next = node.ph_next
|
|
||||||
node.ph_child = None
|
|
||||||
node.ph_next = None
|
|
||||||
node = ph_pairing(child)
|
|
||||||
parent.ph_child = node
|
|
||||||
else:
|
|
||||||
n = parent.ph_child
|
|
||||||
while node is not n.ph_next:
|
|
||||||
n = n.ph_next
|
|
||||||
child = node.ph_child
|
|
||||||
next = node.ph_next
|
|
||||||
node.ph_child = None
|
|
||||||
node.ph_next = None
|
|
||||||
node = ph_pairing(child)
|
|
||||||
if node is None:
|
|
||||||
node = n
|
|
||||||
else:
|
|
||||||
n.ph_next = node
|
|
||||||
node.ph_next = next
|
|
||||||
if next is None:
|
|
||||||
node.ph_rightmost_parent = parent
|
|
||||||
parent.ph_child_last = node
|
|
||||||
return heap
|
|
||||||
|
|
||||||
|
|
||||||
# TaskQueue class based on the above pairing-heap functions.
|
|
||||||
class TaskQueue:
|
|
||||||
def __init__(self):
|
|
||||||
self.heap = None
|
|
||||||
|
|
||||||
def peek(self):
|
|
||||||
return self.heap
|
|
||||||
|
|
||||||
def push_sorted(self, v, key):
|
|
||||||
v.data = None
|
|
||||||
v.ph_key = key
|
|
||||||
v.ph_child = None
|
|
||||||
v.ph_next = None
|
|
||||||
self.heap = ph_meld(v, self.heap)
|
|
||||||
|
|
||||||
def push_head(self, v):
|
|
||||||
self.push_sorted(v, core.ticks())
|
|
||||||
|
|
||||||
def pop_head(self):
|
|
||||||
v = self.heap
|
|
||||||
self.heap = ph_pairing(self.heap.ph_child)
|
|
||||||
return v
|
|
||||||
|
|
||||||
def remove(self, v):
|
|
||||||
self.heap = ph_delete(self.heap, v)
|
|
||||||
|
|
||||||
|
|
||||||
# Task class representing a coroutine, can be waited on and cancelled.
|
|
||||||
class Task:
|
|
||||||
def __init__(self, coro, globals=None):
|
|
||||||
self.coro = coro # Coroutine of this Task
|
|
||||||
self.data = None # General data for queue it is waiting on
|
|
||||||
self.state = True # None, False, True or a TaskQueue instance
|
|
||||||
self.ph_key = 0 # Pairing heap
|
|
||||||
self.ph_child = None # Paring heap
|
|
||||||
self.ph_child_last = None # Paring heap
|
|
||||||
self.ph_next = None # Paring heap
|
|
||||||
self.ph_rightmost_parent = None # Paring heap
|
|
||||||
|
|
||||||
def __await__(self):
|
|
||||||
if not self.state:
|
|
||||||
# Task finished, signal that is has been await'ed on.
|
|
||||||
self.state = False
|
|
||||||
elif self.state is True:
|
|
||||||
# Allocated head of linked list of Tasks waiting on completion of this task.
|
|
||||||
self.state = TaskQueue()
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
if not self.state:
|
|
||||||
if self.data is None:
|
|
||||||
# Task finished but has already been sent to the loop's exception handler.
|
|
||||||
raise StopIteration
|
|
||||||
else:
|
|
||||||
# Task finished, raise return value to caller so it can continue.
|
|
||||||
raise self.data
|
|
||||||
else:
|
|
||||||
# Put calling task on waiting queue.
|
|
||||||
self.state.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to this task that it waits on, to double-link it.
|
|
||||||
core.cur_task.data = self
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
return not self.state
|
|
||||||
|
|
||||||
def cancel(self):
|
|
||||||
# Check if task is already finished.
|
|
||||||
if not self.state:
|
|
||||||
return False
|
|
||||||
# Can't cancel self (not supported yet).
|
|
||||||
if self is core.cur_task:
|
|
||||||
raise RuntimeError("can't cancel self")
|
|
||||||
# If Task waits on another task then forward the cancel to the one it's waiting on.
|
|
||||||
while isinstance(self.data, Task):
|
|
||||||
self = self.data
|
|
||||||
# Reschedule Task as a cancelled task.
|
|
||||||
if hasattr(self.data, "remove"):
|
|
||||||
# Not on the main running queue, remove the task from the queue it's on.
|
|
||||||
self.data.remove(self)
|
|
||||||
core._task_queue.push_head(self)
|
|
||||||
elif core.ticks_diff(self.ph_key, core.ticks()) > 0:
|
|
||||||
# On the main running queue but scheduled in the future, so bring it forward to now.
|
|
||||||
core._task_queue.remove(self)
|
|
||||||
core._task_queue.push_head(self)
|
|
||||||
self.data = core.CancelledError
|
|
||||||
return True
|
|
@ -1,8 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2013-2016 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_PY_UTIME_MP_HAL
|
#if MICROPY_PY_UTIME_MP_HAL
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2013-2016 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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_EXTMOD_UTIME_MPHAL_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
||||||
|
|
||||||
|
32
extmod/vfs.c
32
extmod/vfs.c
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 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 <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -386,8 +407,7 @@ mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
if (vfs == MP_VFS_ROOT) {
|
if (vfs == MP_VFS_ROOT) {
|
||||||
// list the root directory
|
// list the root directory
|
||||||
mp_vfs_ilistdir_it_t *iter = m_new_obj(mp_vfs_ilistdir_it_t);
|
mp_vfs_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = mp_vfs_ilistdir_it_iternext;
|
iter->iternext = mp_vfs_ilistdir_it_iternext;
|
||||||
iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
|
iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
|
||||||
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
||||||
|
32
extmod/vfs.h
32
extmod/vfs.h
@ -1,12 +1,32 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 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_EXTMOD_VFS_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
|
|
||||||
#include "py/lexer.h"
|
#include "py/builtin.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/proto.h"
|
#include "py/proto.h"
|
||||||
|
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS_FAT
|
#if MICROPY_VFS_FAT
|
||||||
@ -54,8 +75,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
|||||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
|
|
||||||
// create new object
|
// create new object
|
||||||
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
fs_user_mount_t *vfs = mp_obj_malloc(fs_user_mount_t, type);
|
||||||
vfs->base.type = type;
|
|
||||||
vfs->fatfs.drv = vfs;
|
vfs->fatfs.drv = vfs;
|
||||||
|
|
||||||
// Initialise underlying block device
|
// Initialise underlying block device
|
||||||
@ -171,8 +191,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new iterator object to list the dir
|
// Create a new iterator object to list the dir
|
||||||
mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t);
|
mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
|
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
|
||||||
iter->is_str = is_str_type;
|
iter->is_str = is_str_type;
|
||||||
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
|
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 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_EXTMOD_VFS_FAT_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
||||||
|
|
||||||
|
@ -1,7 +1,31 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* Original template for this file comes from:
|
||||||
|
* Low level disk I/O module skeleton for FatFs, (C)ChaN, 2013
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 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 "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 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 "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||||
@ -136,6 +157,7 @@ STATIC const mp_arg_t file_open_args[] = {
|
|||||||
};
|
};
|
||||||
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
||||||
|
|
||||||
|
// CIRCUITPY is more careful about validating the open mode.
|
||||||
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
|
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
||||||
@ -210,7 +232,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
|
|||||||
DWORD size = (temp_table[0] + 1) * 2;
|
DWORD size = (temp_table[0] + 1) * 2;
|
||||||
|
|
||||||
// Now allocate the size and construct the map.
|
// Now allocate the size and construct the map.
|
||||||
o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD), false);
|
o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD));
|
||||||
if (o->fp.cltbl != NULL) {
|
if (o->fp.cltbl != NULL) {
|
||||||
o->fp.cltbl[0] = size;
|
o->fp.cltbl[0] = size;
|
||||||
res = f_lseek(&o->fp, CREATE_LINKMAP);
|
res = f_lseek(&o->fp, CREATE_LINKMAP);
|
||||||
|
@ -203,8 +203,7 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args)
|
|||||||
path = vstr_null_terminated_str(&self->cur_dir);
|
path = vstr_null_terminated_str(&self->cur_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj(MP_VFS_LFSx(ilistdir_it_t));
|
MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
|
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
|
||||||
iter->is_str = is_str_type;
|
iter->is_str = is_str_type;
|
||||||
iter->vfs = self;
|
iter->vfs = self;
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2018 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 "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
@ -16,6 +37,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <direct.h> // For mkdir etc.
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _mp_obj_vfs_posix_t {
|
typedef struct _mp_obj_vfs_posix_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
@ -74,8 +98,7 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path
|
|||||||
STATIC mp_obj_t vfs_posix_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 vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
|
|
||||||
mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t);
|
mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type);
|
||||||
vfs->base.type = type;
|
|
||||||
vstr_init(&vfs->root, 0);
|
vstr_init(&vfs->root, 0);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
|
vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
|
||||||
@ -205,8 +228,7 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
|
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
|
||||||
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
vfs_posix_ilistdir_it_t *iter = m_new_obj(vfs_posix_ilistdir_it_t);
|
vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = vfs_posix_ilistdir_it_iternext;
|
iter->iternext = vfs_posix_ilistdir_it_iternext;
|
||||||
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
||||||
const char *path = vfs_posix_get_path_str(self, path_in);
|
const char *path = vfs_posix_get_path_str(self, path_in);
|
||||||
@ -233,7 +255,11 @@ STATIC mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
const char *path = vfs_posix_get_path_str(self, path_in);
|
const char *path = vfs_posix_get_path_str(self, path_in);
|
||||||
MP_THREAD_GIL_EXIT();
|
MP_THREAD_GIL_EXIT();
|
||||||
|
#ifdef _WIN32
|
||||||
|
int ret = mkdir(path);
|
||||||
|
#else
|
||||||
int ret = mkdir(path, 0777);
|
int ret = mkdir(path, 0777);
|
||||||
|
#endif
|
||||||
MP_THREAD_GIL_ENTER();
|
MP_THREAD_GIL_ENTER();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mp_raise_OSError(errno);
|
mp_raise_OSError(errno);
|
||||||
@ -287,6 +313,8 @@ STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_STATVFS
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#define USE_STATFS 1
|
#define USE_STATFS 1
|
||||||
#endif
|
#endif
|
||||||
@ -328,6 +356,8 @@ STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
|
||||||
@ -341,7 +371,9 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
|
||||||
|
#if MICROPY_PY_UOS_STATVFS
|
||||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
||||||
|
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 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_EXTMOD_VFS_POSIX_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
||||||
|
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2018 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 "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/mpthread.h"
|
#include "py/mpthread.h"
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2017 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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 "extmod/virtpin.h"
|
#include "extmod/virtpin.h"
|
||||||
#include "py/proto.h"
|
#include "py/proto.h"
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* 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_EXTMOD_VIRTPIN_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 2582575b500547f26dae04c83e540367c121c7b4
|
Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93
|
@ -1 +1 @@
|
|||||||
Subproject commit f32e7b953ec93f71fcb292074b6d25c7c4355a88
|
Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e
|
@ -1 +1 @@
|
|||||||
Subproject commit 8455eb0b1f5be39638a88df84c9ab360f50ecc90
|
Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86
|
@ -1 +1 @@
|
|||||||
Subproject commit 14f5a0b957a11814339f0e22896243fecc9a78f2
|
Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0
|
@ -1 +1 @@
|
|||||||
Subproject commit bdf4373d734a5c000ef500f70c94b5b24d2663af
|
Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc
|
@ -1 +1 @@
|
|||||||
Subproject commit a1f66529437232d85dbbd3ce7d9688357966cc26
|
Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947
|
@ -1 +1 @@
|
|||||||
Subproject commit 547a7d2a738eeee18e511d71505a645915094395
|
Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a
|
@ -1 +1 @@
|
|||||||
Subproject commit fc3a6a651ee6211b02903ec0bc6808b359bf6d4b
|
Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216
|
@ -1 +1 @@
|
|||||||
Subproject commit 12beb94e4758d6d0f4965b731b086a1bf8c3704e
|
Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39
|
@ -1 +1 @@
|
|||||||
Subproject commit c8bc5431f9ac20ca5b40d0760ac407368d640c4d
|
Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a
|
@ -1 +1 @@
|
|||||||
Subproject commit 67f8c35e2ce4a8abc3cfb24ab5029b40a64857b8
|
Subproject commit 187279a95e5cdd634d233af59352558cea4c1227
|
@ -1 +1 @@
|
|||||||
Subproject commit c8bb6258a0444c31ab5ae69e3af1fffbd7761a99
|
Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1
|
@ -1 +1 @@
|
|||||||
Subproject commit bf7763ef99ca00d1808a9aa47bb1d593a2cc0334
|
Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db
|
@ -1 +1 @@
|
|||||||
Subproject commit 5e4d371d210bbe00e63f83ce698f5bfa8652fa51
|
Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user