Merge MicroPython v1.11 into CircuitPython
This commit is contained in:
parent
8f73270f2b
commit
76033d5115
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -113,7 +113,7 @@
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_Register.git
|
||||
[submodule "extmod/ulab"]
|
||||
path = extmod/ulab
|
||||
url = https://github.com/v923z/micropython-ulab
|
||||
url = https://github.com/adafruit/circuitpython-ulab
|
||||
[submodule "frozen/Adafruit_CircuitPython_ESP32SPI"]
|
||||
path = frozen/Adafruit_CircuitPython_ESP32SPI
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI
|
||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013, 2014 Damien P. George
|
||||
Copyright (c) 2013-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
|
||||
|
@ -886,10 +886,10 @@ uint16_t bleio_adapter_add_attribute(bleio_adapter_obj_t *adapter, mp_obj_t *att
|
||||
uint16_t handle = (uint16_t)adapter->attributes->len;
|
||||
mp_obj_list_append(adapter->attributes, attribute);
|
||||
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
|
||||
if (mp_obj_is_type(attribute, &bleio_service_type)) {
|
||||
adapter->last_added_service_handle = handle;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
if (mp_obj_is_type(attribute, &bleio_characteristic_type)) {
|
||||
adapter->last_added_characteristic_handle = handle;
|
||||
}
|
||||
|
||||
|
@ -33,15 +33,15 @@
|
||||
|
||||
|
||||
bleio_uuid_obj_t *bleio_attribute_get_uuid(mp_obj_t *attribute) {
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
if (mp_obj_is_type(attribute, &bleio_characteristic_type)) {
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute);
|
||||
return characteristic->uuid;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_descriptor_type)) {
|
||||
if (mp_obj_is_type(attribute, &bleio_descriptor_type)) {
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute);
|
||||
return descriptor->uuid;
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(attribute, &bleio_service_type)) {
|
||||
if (mp_obj_is_type(attribute, &bleio_service_type)) {
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute);
|
||||
return service->uuid;
|
||||
}
|
||||
|
@ -213,9 +213,9 @@ bool bleio_characteristic_set_local_value(bleio_characteristic_obj_t *self, mp_b
|
||||
|
||||
self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
|
||||
|
||||
if (MP_OBJ_IS_TYPE(self->observer, &bleio_characteristic_buffer_type)) {
|
||||
if (mp_obj_is_type(self->observer, &bleio_characteristic_buffer_type)) {
|
||||
bleio_characteristic_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo);
|
||||
} else if (MP_OBJ_IS_TYPE(self->observer, &bleio_packet_buffer_type)) {
|
||||
} else if (mp_obj_is_type(self->observer, &bleio_packet_buffer_type)) {
|
||||
bleio_packet_buffer_update(MP_OBJ_FROM_PTR(self->observer), bufinfo);
|
||||
} else {
|
||||
return false;
|
||||
|
@ -644,7 +644,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
||||
// mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
|
||||
// mp_obj_t uuid_obj;
|
||||
// while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
// if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
|
||||
// if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) {
|
||||
// mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist"));
|
||||
// }
|
||||
// bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
|
||||
|
@ -539,7 +539,7 @@ void att_remove_connection(uint16_t conn_handle, uint8_t reason) {
|
||||
.len = sizeof(zero),
|
||||
};
|
||||
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
|
||||
if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) {
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == BLE_UUID_CCCD) {
|
||||
common_hal_bleio_descriptor_set_value(descriptor, &zero_cccd_value);
|
||||
@ -800,7 +800,7 @@ STATIC void process_find_info_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
|
||||
// Fetch the uuid for the given attribute, which might be a characteristic or a descriptor.
|
||||
bleio_uuid_obj_t *uuid;
|
||||
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) {
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (characteristic->handle != handle) {
|
||||
// If the handles don't match, this is the characteristic definition attribute.
|
||||
@ -971,7 +971,7 @@ void process_read_group_req(uint16_t conn_handle, uint16_t mtu, uint8_t dlen, ui
|
||||
}
|
||||
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
|
||||
if (mp_obj_is_type(attribute_obj, &bleio_service_type)) {
|
||||
bleio_service_obj_t *service = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
// Is this a 16-bit or a 128-bit uuid? It must match in size with any previous attribute
|
||||
@ -1083,7 +1083,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
size_t rsp_length = sizeof(rsp_t);
|
||||
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_service_type)) {
|
||||
if (mp_obj_is_type(attribute_obj, &bleio_service_type)) {
|
||||
if (offset) {
|
||||
send_error(conn_handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG, handle, BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
@ -1095,7 +1095,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
common_hal_bleio_uuid_pack_into(service->uuid, rsp->r.value);
|
||||
rsp_length += sizeof_service_uuid;
|
||||
|
||||
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
} else if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) {
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (characteristic->decl_handle == handle) {
|
||||
// Read characteristic declaration. Return properties, value handle, and uuid.
|
||||
@ -1135,7 +1135,7 @@ STATIC void process_read_or_read_blob_req(uint16_t conn_handle, uint16_t mtu, ui
|
||||
memcpy(rsp->r.value, bufinfo.buf + offset, value_length);
|
||||
rsp_length += value_length;
|
||||
}
|
||||
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
|
||||
} else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) {
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
@ -1203,7 +1203,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
|
||||
mp_obj_t *attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
|
||||
if (type_uuid == BLE_UUID_CHARACTERISTIC &&
|
||||
MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) {
|
||||
// Request is for characteristic declarations.
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
@ -1250,7 +1250,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
|
||||
rsp_length += data_length;
|
||||
no_data = false;
|
||||
|
||||
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
|
||||
} else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) {
|
||||
// See if request is for a descriptor value with a 16-bit UUID, such as the CCCD.
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) == type_uuid) {
|
||||
@ -1271,7 +1271,7 @@ STATIC void process_read_type_req(uint16_t conn_handle, uint16_t mtu, uint8_t dl
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
} else if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) {
|
||||
// See if request is for a characteristic value with a 16-bit UUID.
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
if (bleio_uuid_get_uuid16_or_unknown(characteristic->uuid) == type_uuid) {
|
||||
@ -1359,7 +1359,7 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t
|
||||
|
||||
mp_obj_t attribute_obj = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, req->handle);
|
||||
|
||||
if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_characteristic_type)) {
|
||||
if (mp_obj_is_type(attribute_obj, &bleio_characteristic_type)) {
|
||||
bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(attribute_obj);
|
||||
|
||||
// Don't write the characteristic declaration.
|
||||
@ -1377,7 +1377,7 @@ STATIC void process_write_req_or_cmd(uint16_t conn_handle, uint16_t mtu, uint8_t
|
||||
// Just change the local value. Don't fire off notifications, etc.
|
||||
bleio_characteristic_set_local_value(characteristic, &bufinfo);
|
||||
|
||||
} else if (MP_OBJ_IS_TYPE(attribute_obj, &bleio_descriptor_type)) {
|
||||
} else if (mp_obj_is_type(attribute_obj, &bleio_descriptor_type)) {
|
||||
bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(attribute_obj);
|
||||
// Only CCCD's are writable.
|
||||
if (bleio_uuid_get_uuid16_or_unknown(descriptor->uuid) != BLE_UUID_CCCD) {
|
||||
@ -1427,7 +1427,7 @@ STATIC void process_prepare_write_req(uint16_t conn_handle, uint16_t mtu, uint8_
|
||||
|
||||
mp_obj_t *attribute = bleio_adapter_get_attribute(&common_hal_bleio_adapter_obj, handle);
|
||||
|
||||
if (!MP_OBJ_IS_TYPE(attribute, &bleio_characteristic_type)) {
|
||||
if (!mp_obj_is_type(attribute, &bleio_characteristic_type)) {
|
||||
send_error(conn_handle, BT_ATT_OP_PREPARE_WRITE_REQ, handle, BT_ATT_ERR_ATTRIBUTE_NOT_LONG);
|
||||
return;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ Match objects
|
||||
Match objects as returned by `match()` and `search()` methods, and passed
|
||||
to the replacement function in `sub()`.
|
||||
|
||||
.. method:: match.group([index])
|
||||
.. method:: match.group(index)
|
||||
|
||||
Return matching (sub)string. *index* is 0 for entire match,
|
||||
1 and above for each capturing group. Only numeric groups are supported.
|
||||
|
@ -15,6 +15,7 @@
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream);
|
||||
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);
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
static void check_not_unicode(const mp_obj_t arg) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (MP_OBJ_IS_STR(arg)) {
|
||||
if (mp_obj_is_str(arg)) {
|
||||
mp_raise_TypeError(translate("a bytes-like object is required"));
|
||||
}
|
||||
#endif
|
||||
|
@ -118,13 +118,13 @@ STATIC void uctypes_struct_print(const mp_print_t *print, mp_obj_t self_in, mp_p
|
||||
(void)kind;
|
||||
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
const char *typen = "unk";
|
||||
if (MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)
|
||||
if (mp_obj_is_type(self->desc, &mp_type_dict)
|
||||
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
||||
|| MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict)
|
||||
|| mp_obj_is_type(self->desc, &mp_type_ordereddict)
|
||||
#endif
|
||||
) {
|
||||
typen = "STRUCT";
|
||||
} else if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
|
||||
} else if (mp_obj_is_type(self->desc, &mp_type_tuple)) {
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
|
||||
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
|
||||
uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
|
||||
@ -195,14 +195,14 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_
|
||||
}
|
||||
|
||||
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size) {
|
||||
if (!MP_OBJ_IS_TYPE(desc_in, &mp_type_dict)
|
||||
if (!mp_obj_is_type(desc_in, &mp_type_dict)
|
||||
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
||||
&& !MP_OBJ_IS_TYPE(desc_in, &mp_type_ordereddict)
|
||||
&& !mp_obj_is_type(desc_in, &mp_type_ordereddict)
|
||||
#endif
|
||||
) {
|
||||
if (MP_OBJ_IS_TYPE(desc_in, &mp_type_tuple)) {
|
||||
if (mp_obj_is_type(desc_in, &mp_type_tuple)) {
|
||||
return uctypes_struct_agg_size((mp_obj_tuple_t *)MP_OBJ_TO_PTR(desc_in), layout_type, max_field_size);
|
||||
} else if (MP_OBJ_IS_SMALL_INT(desc_in)) {
|
||||
} else if (mp_obj_is_small_int(desc_in)) {
|
||||
// We allow sizeof on both type definitions and structures/structure fields,
|
||||
// but scalar structure field is lowered into native Python int, so all
|
||||
// type info is lost. So, we cannot say if it's scalar type description,
|
||||
@ -216,9 +216,9 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
|
||||
mp_uint_t total_size = 0;
|
||||
|
||||
for (mp_uint_t i = 0; i < d->map.alloc; i++) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(&d->map, i)) {
|
||||
if (mp_map_slot_is_filled(&d->map, i)) {
|
||||
mp_obj_t v = d->map.table[i].value;
|
||||
if (MP_OBJ_IS_SMALL_INT(v)) {
|
||||
if (mp_obj_is_small_int(v)) {
|
||||
mp_uint_t offset = MP_OBJ_SMALL_INT_VALUE(v);
|
||||
mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS);
|
||||
offset &= VALUE_MASK(VAL_TYPE_BITS);
|
||||
@ -233,7 +233,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
|
||||
total_size = offset + s;
|
||||
}
|
||||
} else {
|
||||
if (!MP_OBJ_IS_TYPE(v, &mp_type_tuple)) {
|
||||
if (!mp_obj_is_type(v, &mp_type_tuple)) {
|
||||
syntax_error();
|
||||
}
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(v);
|
||||
@ -257,13 +257,13 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_
|
||||
STATIC mp_obj_t uctypes_struct_sizeof(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t obj_in = args[0];
|
||||
mp_uint_t max_field_size = 0;
|
||||
if (MP_OBJ_IS_TYPE(obj_in, &mp_type_bytearray)) {
|
||||
if (mp_obj_is_type(obj_in, &mp_type_bytearray)) {
|
||||
return mp_obj_len(obj_in);
|
||||
}
|
||||
int layout_type = LAYOUT_NATIVE;
|
||||
// We can apply sizeof either to structure definition (a dict)
|
||||
// or to instantiated structure
|
||||
if (MP_OBJ_IS_TYPE(obj_in, &uctypes_struct_type)) {
|
||||
if (mp_obj_is_type(obj_in, &uctypes_struct_type)) {
|
||||
if (n_args != 1) {
|
||||
mp_raise_TypeError(NULL);
|
||||
}
|
||||
@ -400,16 +400,16 @@ STATIC void set_aligned(uint val_type, void *p, mp_int_t index, mp_obj_t val) {
|
||||
STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set_val) {
|
||||
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_dict)
|
||||
if (!mp_obj_is_type(self->desc, &mp_type_dict)
|
||||
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
||||
&& !MP_OBJ_IS_TYPE(self->desc, &mp_type_ordereddict)
|
||||
&& !mp_obj_is_type(self->desc, &mp_type_ordereddict)
|
||||
#endif
|
||||
) {
|
||||
mp_raise_TypeError(translate("struct: no fields"));
|
||||
}
|
||||
|
||||
mp_obj_t deref = mp_obj_dict_get(self->desc, MP_OBJ_NEW_QSTR(attr));
|
||||
if (MP_OBJ_IS_SMALL_INT(deref)) {
|
||||
if (mp_obj_is_small_int(deref)) {
|
||||
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(deref);
|
||||
mp_uint_t val_type = GET_TYPE(offset, VAL_TYPE_BITS);
|
||||
offset &= VALUE_MASK(VAL_TYPE_BITS);
|
||||
@ -470,7 +470,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
||||
return MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
if (!MP_OBJ_IS_TYPE(deref, &mp_type_tuple)) {
|
||||
if (!mp_obj_is_type(deref, &mp_type_tuple)) {
|
||||
syntax_error();
|
||||
}
|
||||
|
||||
@ -537,7 +537,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
} else {
|
||||
// load / store
|
||||
if (!MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
|
||||
if (!mp_obj_is_type(self->desc, &mp_type_tuple)) {
|
||||
mp_raise_TypeError(translate("struct: cannot index"));
|
||||
}
|
||||
|
||||
@ -588,7 +588,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
||||
|
||||
} else if (agg_type == PTR) {
|
||||
byte *p = *(void **)self->addr;
|
||||
if (MP_OBJ_IS_SMALL_INT(t->items[1])) {
|
||||
if (mp_obj_is_small_int(t->items[1])) {
|
||||
uint val_type = GET_TYPE(MP_OBJ_SMALL_INT_VALUE(t->items[1]), VAL_TYPE_BITS);
|
||||
return get_aligned(val_type, p, index);
|
||||
} else {
|
||||
@ -612,7 +612,7 @@ STATIC mp_obj_t uctypes_struct_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_INT:
|
||||
if (MP_OBJ_IS_TYPE(self->desc, &mp_type_tuple)) {
|
||||
if (mp_obj_is_type(self->desc, &mp_type_tuple)) {
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(self->desc);
|
||||
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
|
||||
uint agg_type = GET_TYPE(offset, AGG_TYPE_BITS);
|
||||
|
@ -88,12 +88,16 @@ STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
|
||||
|
||||
static void check_not_unicode(const mp_obj_t arg) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (MP_OBJ_IS_STR(arg)) {
|
||||
if (mp_obj_is_str(arg)) {
|
||||
mp_raise_TypeError(translate("a bytes-like object is required"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MICROPY_PY_UHASHLIB_SHA256
|
||||
#include "crypto-algorithms/sha256.c"
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 0, 1, false);
|
||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
|
||||
@ -336,8 +340,4 @@ const mp_obj_module_t mp_module_uhashlib = {
|
||||
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
||||
};
|
||||
|
||||
#if MICROPY_PY_UHASHLIB_SHA256
|
||||
#include "crypto-algorithms/sha256.c"
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_PY_UHASHLIB
|
||||
|
@ -13,7 +13,7 @@
|
||||
// the algorithm here is modelled on CPython's heapq.py
|
||||
|
||||
STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) {
|
||||
if (!MP_OBJ_IS_TYPE(heap_in, &mp_type_list)) {
|
||||
if (!mp_obj_is_type(heap_in, &mp_type_list)) {
|
||||
mp_raise_TypeError(translate("heap must be a list"));
|
||||
}
|
||||
return MP_OBJ_TO_PTR(heap_in);
|
||||
|
@ -243,7 +243,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
|
||||
cur = S_CUR(s);
|
||||
if (cur == '.' || cur == 'E' || cur == 'e') {
|
||||
flt = true;
|
||||
} else if (cur == '-' || unichar_isdigit(cur)) {
|
||||
} else if (cur == '+' || cur == '-' || unichar_isdigit(cur)) {
|
||||
// pass
|
||||
} else {
|
||||
break;
|
||||
|
@ -180,8 +180,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform);
|
||||
|
||||
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
|
||||
|
||||
#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC
|
||||
STATIC mp_obj_t mod_urandom___init__() {
|
||||
mod_urandom_seed(MP_OBJ_NEW_SMALL_INT(MICROPY_PY_URANDOM_SEED_INIT_FUNC));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom___init___obj, mod_urandom___init__);
|
||||
#endif
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_urandom_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_urandom) },
|
||||
#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC
|
||||
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&mod_urandom___init___obj) },
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_urandom_getrandbits_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_urandom_seed_obj) },
|
||||
#if MICROPY_PY_URANDOM_EXTRA_FUNCS
|
||||
|
@ -1,5 +1,6 @@
|
||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
@ -57,7 +58,7 @@ STATIC void poll_map_add(mp_map_t *poll_map, const mp_obj_t *obj, mp_uint_t obj_
|
||||
STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) {
|
||||
mp_uint_t n_ready = 0;
|
||||
for (mp_uint_t i = 0; i < poll_map->alloc; ++i) {
|
||||
if (!MP_MAP_SLOT_IS_FILLED(poll_map, i)) {
|
||||
if (!mp_map_slot_is_filled(poll_map, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ STATIC mp_uint_t poll_map_poll(mp_map_t *poll_map, size_t *rwx_num) {
|
||||
}
|
||||
|
||||
/// \function select(rlist, wlist, xlist[, timeout])
|
||||
STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
|
||||
// get array data from tuple/list arguments
|
||||
size_t rwx_len[3];
|
||||
mp_obj_t *r_array, *w_array, *x_array;
|
||||
@ -135,7 +136,7 @@ STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) {
|
||||
list_array[2] = mp_obj_new_list(rwx_len[2], NULL);
|
||||
rwx_len[0] = rwx_len[1] = rwx_len[2] = 0;
|
||||
for (mp_uint_t i = 0; i < poll_map.alloc; ++i) {
|
||||
if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) {
|
||||
if (!mp_map_slot_is_filled(&poll_map, i)) {
|
||||
continue;
|
||||
}
|
||||
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(poll_map.table[i].value);
|
||||
@ -170,7 +171,7 @@ typedef struct _mp_obj_poll_t {
|
||||
} mp_obj_poll_t;
|
||||
|
||||
/// \method register(obj[, eventmask])
|
||||
STATIC mp_obj_t poll_register(uint n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
mp_uint_t flags;
|
||||
if (n_args == 3) {
|
||||
@ -246,7 +247,7 @@ STATIC mp_obj_t poll_poll(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_list_t *ret_list = MP_OBJ_TO_PTR(mp_obj_new_list(n_ready, NULL));
|
||||
n_ready = 0;
|
||||
for (mp_uint_t i = 0; i < self->poll_map.alloc; ++i) {
|
||||
if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) {
|
||||
if (!mp_map_slot_is_filled(&self->poll_map, i)) {
|
||||
continue;
|
||||
}
|
||||
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
|
||||
@ -289,7 +290,7 @@ STATIC mp_obj_t poll_iternext(mp_obj_t self_in) {
|
||||
|
||||
for (mp_uint_t i = self->iter_idx; i < self->poll_map.alloc; ++i) {
|
||||
self->iter_idx++;
|
||||
if (!MP_MAP_SLOT_IS_FILLED(&self->poll_map, i)) {
|
||||
if (!mp_map_slot_is_filled(&self->poll_map, i)) {
|
||||
continue;
|
||||
}
|
||||
poll_obj_t *poll_obj = MP_OBJ_TO_PTR(self->poll_map.table[i].value);
|
||||
|
@ -1,244 +0,0 @@
|
||||
// Copyright (c) 2015-2017 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 "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#if MICROPY_PY_USSL && MICROPY_SSL_AXTLS
|
||||
|
||||
#include "ssl.h"
|
||||
|
||||
typedef struct _mp_obj_ssl_socket_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t sock;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl_sock;
|
||||
byte *buf;
|
||||
uint32_t bytes_left;
|
||||
} mp_obj_ssl_socket_t;
|
||||
|
||||
struct ssl_args {
|
||||
mp_arg_val_t key;
|
||||
mp_arg_val_t cert;
|
||||
mp_arg_val_t server_side;
|
||||
mp_arg_val_t server_hostname;
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t ussl_socket_type;
|
||||
|
||||
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
|
||||
#if MICROPY_PY_USSL_FINALISER
|
||||
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
|
||||
#else
|
||||
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
|
||||
#endif
|
||||
o->base.type = &ussl_socket_type;
|
||||
o->buf = NULL;
|
||||
o->bytes_left = 0;
|
||||
o->sock = sock;
|
||||
|
||||
uint32_t options = SSL_SERVER_VERIFY_LATER;
|
||||
if (args->key.u_obj != mp_const_none) {
|
||||
options |= SSL_NO_DEFAULT_KEY;
|
||||
}
|
||||
if ((o->ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) {
|
||||
mp_raise_OSError(MP_EINVAL);
|
||||
}
|
||||
|
||||
if (args->key.u_obj != mp_const_none) {
|
||||
size_t len;
|
||||
const byte *data = (const byte *)mp_obj_str_get_data(args->key.u_obj, &len);
|
||||
int res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_RSA_KEY, data, len, NULL);
|
||||
if (res != SSL_OK) {
|
||||
mp_raise_ValueError(translate("invalid key"));
|
||||
}
|
||||
|
||||
data = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &len);
|
||||
res = ssl_obj_memory_load(o->ssl_ctx, SSL_OBJ_X509_CERT, data, len, NULL);
|
||||
if (res != SSL_OK) {
|
||||
mp_raise_ValueError(translate("invalid cert"));
|
||||
}
|
||||
}
|
||||
|
||||
if (args->server_side.u_bool) {
|
||||
o->ssl_sock = ssl_server_new(o->ssl_ctx, (long)sock);
|
||||
} else {
|
||||
SSL_EXTENSIONS *ext = ssl_ext_new();
|
||||
|
||||
if (args->server_hostname.u_obj != mp_const_none) {
|
||||
ext->host_name = (char *)mp_obj_str_get_str(args->server_hostname.u_obj);
|
||||
}
|
||||
|
||||
o->ssl_sock = ssl_client_new(o->ssl_ctx, (long)sock, NULL, 0, ext);
|
||||
|
||||
int res = ssl_handshake_status(o->ssl_sock);
|
||||
// Pointer to SSL_EXTENSIONS as being passed to ssl_client_new()
|
||||
// is saved in ssl_sock->extensions.
|
||||
// As of axTLS 2.1.3, extensions aren't used beyond the initial
|
||||
// handshake, and that's pretty much how it's expected to be. So
|
||||
// we allocate them on stack and reset the pointer after handshake.
|
||||
|
||||
if (res != SSL_OK) {
|
||||
printf("ssl_handshake_status: %d\n", res);
|
||||
ssl_display_error(res);
|
||||
mp_raise_OSError(MP_EIO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "<_SSLSocket %p>", self->ssl_sock);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
|
||||
if (o->ssl_sock == NULL) {
|
||||
*errcode = EBADF;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
while (o->bytes_left == 0) {
|
||||
mp_int_t r = ssl_read(o->ssl_sock, &o->buf);
|
||||
if (r == SSL_OK) {
|
||||
// SSL_OK from ssl_read() means "everything is ok, but there's
|
||||
// no user data yet". So, we just keep reading.
|
||||
continue;
|
||||
}
|
||||
if (r < 0) {
|
||||
if (r == SSL_CLOSE_NOTIFY || r == SSL_ERROR_CONN_LOST) {
|
||||
// EOF
|
||||
return 0;
|
||||
}
|
||||
if (r == SSL_EAGAIN) {
|
||||
r = MP_EAGAIN;
|
||||
}
|
||||
*errcode = r;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
o->bytes_left = r;
|
||||
}
|
||||
|
||||
if (size > o->bytes_left) {
|
||||
size = o->bytes_left;
|
||||
}
|
||||
memcpy(buf, o->buf, size);
|
||||
o->buf += size;
|
||||
o->bytes_left -= size;
|
||||
return size;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
|
||||
if (o->ssl_sock == NULL) {
|
||||
*errcode = EBADF;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
mp_int_t r = ssl_write(o->ssl_sock, buf, size);
|
||||
if (r < 0) {
|
||||
*errcode = r;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
|
||||
if (request == MP_STREAM_CLOSE && self->ssl_sock != NULL) {
|
||||
ssl_free(self->ssl_sock);
|
||||
ssl_ctx_free(self->ssl_ctx);
|
||||
self->ssl_sock = NULL;
|
||||
}
|
||||
// Pass all requests down to the underlying socket
|
||||
return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
|
||||
// Currently supports only blocking mode
|
||||
(void)self_in;
|
||||
if (!mp_obj_is_true(flag_in)) {
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
|
||||
|
||||
STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
#if MICROPY_PY_USSL_FINALISER
|
||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t ussl_socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
.ioctl = socket_ioctl,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t ussl_socket_type = {
|
||||
{ &mp_type_type },
|
||||
// Save on qstr's, reuse same as for module
|
||||
.name = MP_QSTR_ussl,
|
||||
.print = socket_print,
|
||||
.getiter = NULL,
|
||||
.iternext = NULL,
|
||||
.protocol = &ussl_socket_stream_p,
|
||||
.locals_dict = (void *)&ussl_socket_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// TODO: Implement more args
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
{ MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
|
||||
};
|
||||
|
||||
// TODO: Check that sock implements stream protocol
|
||||
mp_obj_t sock = pos_args[0];
|
||||
|
||||
struct ssl_args 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);
|
||||
|
||||
return MP_OBJ_FROM_PTR(socket_new(sock, &args));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ussl = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_ssl_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_USSL
|
@ -1,330 +0,0 @@
|
||||
// Copyright (c) 2016 Linaro Ltd.
|
||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_PY_USSL && MICROPY_SSL_MBEDTLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h> // needed because mp_is_nonblocking_error uses system error codes
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
|
||||
// mbedtls_time_t
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#include "mbedtls/pk.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/debug.h"
|
||||
|
||||
typedef struct _mp_obj_ssl_socket_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t sock;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_ssl_config conf;
|
||||
mbedtls_x509_crt cacert;
|
||||
mbedtls_x509_crt cert;
|
||||
mbedtls_pk_context pkey;
|
||||
} mp_obj_ssl_socket_t;
|
||||
|
||||
struct ssl_args {
|
||||
mp_arg_val_t key;
|
||||
mp_arg_val_t cert;
|
||||
mp_arg_val_t server_side;
|
||||
mp_arg_val_t server_hostname;
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t ussl_socket_type;
|
||||
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
STATIC void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) {
|
||||
(void)ctx;
|
||||
(void)level;
|
||||
printf("DBG:%s:%04d: %s\n", file, line, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC int _mbedtls_ssl_send(void *ctx, const byte *buf, size_t len) {
|
||||
mp_obj_t sock = *(mp_obj_t *)ctx;
|
||||
|
||||
const mp_stream_p_t *sock_stream = mp_get_stream(sock);
|
||||
int err;
|
||||
|
||||
mp_uint_t out_sz = sock_stream->write(sock, buf, len, &err);
|
||||
if (out_sz == MP_STREAM_ERROR) {
|
||||
if (mp_is_nonblocking_error(err)) {
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
}
|
||||
return -err;
|
||||
} else {
|
||||
return out_sz;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
|
||||
mp_obj_t sock = *(mp_obj_t *)ctx;
|
||||
|
||||
const mp_stream_p_t *sock_stream = mp_get_stream(sock);
|
||||
int err;
|
||||
|
||||
mp_uint_t out_sz = sock_stream->read(sock, buf, len, &err);
|
||||
if (out_sz == MP_STREAM_ERROR) {
|
||||
if (mp_is_nonblocking_error(err)) {
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
return -err;
|
||||
} else {
|
||||
return out_sz;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, struct ssl_args *args) {
|
||||
// Verify the socket object has the full stream protocol
|
||||
mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
||||
|
||||
#if MICROPY_PY_USSL_FINALISER
|
||||
mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
|
||||
#else
|
||||
mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t);
|
||||
#endif
|
||||
o->base.type = &ussl_socket_type;
|
||||
o->sock = sock;
|
||||
|
||||
int ret;
|
||||
mbedtls_ssl_init(&o->ssl);
|
||||
mbedtls_ssl_config_init(&o->conf);
|
||||
mbedtls_x509_crt_init(&o->cacert);
|
||||
mbedtls_x509_crt_init(&o->cert);
|
||||
mbedtls_pk_init(&o->pkey);
|
||||
mbedtls_ctr_drbg_init(&o->ctr_drbg);
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
// Debug level (0-4)
|
||||
mbedtls_debug_set_threshold(0);
|
||||
#endif
|
||||
|
||||
mbedtls_entropy_init(&o->entropy);
|
||||
const byte seed[] = "upy";
|
||||
ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, mbedtls_entropy_func, &o->entropy, seed, sizeof(seed));
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_config_defaults(&o->conf,
|
||||
args->server_side.u_bool ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg);
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL);
|
||||
#endif
|
||||
|
||||
ret = mbedtls_ssl_setup(&o->ssl, &o->conf);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (args->server_hostname.u_obj != mp_const_none) {
|
||||
const char *sni = mp_obj_str_get_str(args->server_hostname.u_obj);
|
||||
ret = mbedtls_ssl_set_hostname(&o->ssl, sni);
|
||||
if (ret != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL);
|
||||
|
||||
if (args->key.u_obj != MP_OBJ_NULL) {
|
||||
size_t key_len;
|
||||
const byte *key = (const byte *)mp_obj_str_get_data(args->key.u_obj, &key_len);
|
||||
// len should include terminating null
|
||||
ret = mbedtls_pk_parse_key(&o->pkey, key, key_len + 1, NULL, 0);
|
||||
assert(ret == 0);
|
||||
|
||||
size_t cert_len;
|
||||
const byte *cert = (const byte *)mp_obj_str_get_data(args->cert.u_obj, &cert_len);
|
||||
// len should include terminating null
|
||||
ret = mbedtls_x509_crt_parse(&o->cert, cert, cert_len + 1);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = mbedtls_ssl_conf_own_cert(&o->conf, &o->cert, &o->pkey);
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
printf("mbedtls_ssl_handshake error: -%x\n", -ret);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
|
||||
cleanup:
|
||||
mbedtls_pk_free(&o->pkey);
|
||||
mbedtls_x509_crt_free(&o->cert);
|
||||
mbedtls_x509_crt_free(&o->cacert);
|
||||
mbedtls_ssl_free(&o->ssl);
|
||||
mbedtls_ssl_config_free(&o->conf);
|
||||
mbedtls_ctr_drbg_free(&o->ctr_drbg);
|
||||
mbedtls_entropy_free(&o->entropy);
|
||||
|
||||
if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) {
|
||||
mp_raise_OSError(MP_ENOMEM);
|
||||
} else {
|
||||
mp_raise_OSError(MP_EIO);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
if (!mp_obj_is_true(binary_form)) {
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(&o->ssl);
|
||||
return mp_obj_new_bytes(peer_cert->raw.p, peer_cert->raw.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_getpeercert_obj, mod_ssl_getpeercert);
|
||||
|
||||
STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "<_SSLSocket %p>", self);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
|
||||
int ret = mbedtls_ssl_read(&o->ssl, buf, size);
|
||||
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
||||
// end of stream
|
||||
return 0;
|
||||
}
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
ret = MP_EWOULDBLOCK;
|
||||
}
|
||||
*errcode = ret;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
|
||||
int ret = mbedtls_ssl_write(&o->ssl, buf, size);
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
ret = MP_EWOULDBLOCK;
|
||||
}
|
||||
*errcode = ret;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
|
||||
mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_t sock = o->sock;
|
||||
mp_obj_t dest[3];
|
||||
mp_load_method(sock, MP_QSTR_setblocking, dest);
|
||||
dest[2] = flag_in;
|
||||
return mp_call_method_n_kw(1, 0, dest);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
|
||||
|
||||
STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
|
||||
if (request == MP_STREAM_CLOSE) {
|
||||
mbedtls_pk_free(&self->pkey);
|
||||
mbedtls_x509_crt_free(&self->cert);
|
||||
mbedtls_x509_crt_free(&self->cacert);
|
||||
mbedtls_ssl_free(&self->ssl);
|
||||
mbedtls_ssl_config_free(&self->conf);
|
||||
mbedtls_ctr_drbg_free(&self->ctr_drbg);
|
||||
mbedtls_entropy_free(&self->entropy);
|
||||
}
|
||||
// Pass all requests down to the underlying socket
|
||||
return mp_get_stream(self->sock)->ioctl(self->sock, request, arg, errcode);
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
#if MICROPY_PY_USSL_FINALISER
|
||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t ussl_socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
.ioctl = socket_ioctl,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t ussl_socket_type = {
|
||||
{ &mp_type_type },
|
||||
// Save on qstr's, reuse same as for module
|
||||
.name = MP_QSTR_ussl,
|
||||
.print = socket_print,
|
||||
.getiter = NULL,
|
||||
.iternext = NULL,
|
||||
.protocol = &ussl_socket_stream_p,
|
||||
.locals_dict = (void *)&ussl_socket_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// TODO: Implement more args
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// TODO: Check that sock implements stream protocol
|
||||
mp_obj_t sock = pos_args[0];
|
||||
|
||||
struct ssl_args 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);
|
||||
|
||||
return MP_OBJ_FROM_PTR(socket_new(sock, &args));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ussl) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&mod_ssl_wrap_socket_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_ssl_globals, mp_module_ssl_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ussl = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_ssl_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_USSL
|
@ -126,7 +126,7 @@ STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
|
||||
mp_raise_IndexError(translate("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) {
|
||||
if (!mp_obj_is_type(list_ref, &mp_type_list) || ret->len < 3) {
|
||||
mp_raise_TypeError(NULL);
|
||||
}
|
||||
|
||||
|
10
extmod/moduwebsocket.h
Normal file
10
extmod/moduwebsocket.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H
|
||||
#define MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H
|
||||
|
||||
#define FRAME_OPCODE_MASK 0x0f
|
||||
enum {
|
||||
FRAME_CONT, FRAME_TXT, FRAME_BIN,
|
||||
FRAME_CLOSE = 0x8, FRAME_PING, FRAME_PONG
|
||||
};
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_MODUWEBSOCKET_H
|
@ -13,7 +13,7 @@
|
||||
#ifdef MICROPY_PY_WEBREPL_DELAY
|
||||
#include "py/mphal.h"
|
||||
#endif
|
||||
#include "extmod/modwebsocket.h"
|
||||
#include "extmod/moduwebsocket.h"
|
||||
|
||||
#if MICROPY_PY_WEBREPL
|
||||
|
||||
@ -87,6 +87,15 @@ STATIC mp_obj_t webrepl_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
||||
return o;
|
||||
}
|
||||
|
||||
STATIC void check_file_op_finished(mp_obj_webrepl_t *self) {
|
||||
if (self->data_to_recv == 0) {
|
||||
mp_stream_close(self->cur_file);
|
||||
self->hdr_to_recv = sizeof(struct webrepl_file);
|
||||
DEBUG_printf("webrepl: Finished file operation %d\n", self->hdr.type);
|
||||
write_webrepl_resp(self->sock, 0);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int write_file_chunk(mp_obj_webrepl_t *self) {
|
||||
const mp_stream_p_t *file_stream = mp_get_stream(self->cur_file);
|
||||
byte readbuf[2 + 256];
|
||||
@ -139,6 +148,7 @@ STATIC void handle_op(mp_obj_webrepl_t *self) {
|
||||
|
||||
if (self->hdr.type == PUT_FILE) {
|
||||
self->data_to_recv = self->hdr.size;
|
||||
check_file_op_finished(self);
|
||||
} else if (self->hdr.type == GET_FILE) {
|
||||
self->data_to_recv = 1;
|
||||
}
|
||||
@ -245,12 +255,7 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
|
||||
}
|
||||
}
|
||||
|
||||
if (self->data_to_recv == 0) {
|
||||
mp_stream_close(self->cur_file);
|
||||
self->hdr_to_recv = sizeof(struct webrepl_file);
|
||||
DEBUG_printf("webrepl: Finished file operation %d\n", self->hdr.type);
|
||||
write_webrepl_resp(self->sock, 0);
|
||||
}
|
||||
check_file_op_finished(self);
|
||||
|
||||
#ifdef MICROPY_PY_WEBREPL_DELAY
|
||||
// Some platforms may have broken drivers and easily gets
|
||||
|
@ -1,294 +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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "extmod/modwebsocket.h"
|
||||
|
||||
#if MICROPY_PY_WEBSOCKET
|
||||
|
||||
enum { FRAME_HEADER, FRAME_OPT, PAYLOAD, CONTROL };
|
||||
|
||||
enum { BLOCKING_WRITE = 0x80 };
|
||||
|
||||
typedef struct _mp_obj_websocket_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t sock;
|
||||
uint32_t msg_sz;
|
||||
byte mask[4];
|
||||
byte state;
|
||||
byte to_recv;
|
||||
byte mask_pos;
|
||||
byte buf_pos;
|
||||
byte buf[6];
|
||||
byte opts;
|
||||
// Copy of last data frame flags
|
||||
byte ws_flags;
|
||||
// Copy of current frame flags
|
||||
byte last_flags;
|
||||
} mp_obj_websocket_t;
|
||||
|
||||
STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode);
|
||||
|
||||
STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 1, 2, false);
|
||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
||||
mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t);
|
||||
o->base.type = type;
|
||||
o->sock = args[0];
|
||||
o->state = FRAME_HEADER;
|
||||
o->to_recv = 2;
|
||||
o->mask_pos = 0;
|
||||
o->buf_pos = 0;
|
||||
o->opts = FRAME_TXT;
|
||||
if (n_args > 1 && args[1] == mp_const_true) {
|
||||
o->opts |= BLOCKING_WRITE;
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
const mp_stream_p_t *stream_p = mp_get_stream(self->sock);
|
||||
while (1) {
|
||||
if (self->to_recv != 0) {
|
||||
mp_uint_t out_sz = stream_p->read(self->sock, self->buf + self->buf_pos, self->to_recv, errcode);
|
||||
if (out_sz == 0 || out_sz == MP_STREAM_ERROR) {
|
||||
return out_sz;
|
||||
}
|
||||
self->buf_pos += out_sz;
|
||||
self->to_recv -= out_sz;
|
||||
if (self->to_recv != 0) {
|
||||
*errcode = MP_EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
switch (self->state) {
|
||||
case FRAME_HEADER: {
|
||||
// TODO: Split frame handling below is untested so far, so conservatively disable it
|
||||
assert(self->buf[0] & 0x80);
|
||||
|
||||
// "Control frames MAY be injected in the middle of a fragmented message."
|
||||
// So, they must be processed before data frames (and not alter
|
||||
// self->ws_flags)
|
||||
byte frame_type = self->buf[0];
|
||||
self->last_flags = frame_type;
|
||||
frame_type &= FRAME_OPCODE_MASK;
|
||||
|
||||
if ((self->buf[0] & FRAME_OPCODE_MASK) == FRAME_CONT) {
|
||||
// Preserve previous frame type
|
||||
self->ws_flags = (self->ws_flags & FRAME_OPCODE_MASK) | (self->buf[0] & ~FRAME_OPCODE_MASK);
|
||||
} else {
|
||||
self->ws_flags = self->buf[0];
|
||||
}
|
||||
|
||||
// Reset mask in case someone will use "simplified" protocol
|
||||
// without masks.
|
||||
memset(self->mask, 0, sizeof(self->mask));
|
||||
|
||||
int to_recv = 0;
|
||||
size_t sz = self->buf[1] & 0x7f;
|
||||
if (sz == 126) {
|
||||
// Msg size is next 2 bytes
|
||||
to_recv += 2;
|
||||
} else if (sz == 127) {
|
||||
// Msg size is next 8 bytes
|
||||
assert(0);
|
||||
}
|
||||
if (self->buf[1] & 0x80) {
|
||||
// Next 4 bytes is mask
|
||||
to_recv += 4;
|
||||
}
|
||||
|
||||
self->buf_pos = 0;
|
||||
self->to_recv = to_recv;
|
||||
self->msg_sz = sz; // May be overridden by FRAME_OPT
|
||||
if (to_recv != 0) {
|
||||
self->state = FRAME_OPT;
|
||||
} else {
|
||||
if (frame_type >= FRAME_CLOSE) {
|
||||
self->state = CONTROL;
|
||||
} else {
|
||||
self->state = PAYLOAD;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case FRAME_OPT: {
|
||||
if ((self->buf_pos & 3) == 2) {
|
||||
// First two bytes are message length
|
||||
self->msg_sz = (self->buf[0] << 8) | self->buf[1];
|
||||
}
|
||||
if (self->buf_pos >= 4) {
|
||||
// Last 4 bytes is mask
|
||||
memcpy(self->mask, self->buf + self->buf_pos - 4, 4);
|
||||
}
|
||||
self->buf_pos = 0;
|
||||
if ((self->last_flags & FRAME_OPCODE_MASK) >= FRAME_CLOSE) {
|
||||
self->state = CONTROL;
|
||||
} else {
|
||||
self->state = PAYLOAD;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case PAYLOAD:
|
||||
case CONTROL: {
|
||||
mp_uint_t out_sz = 0;
|
||||
if (self->msg_sz == 0) {
|
||||
// In case message had zero payload
|
||||
goto no_payload;
|
||||
}
|
||||
|
||||
size_t sz = MIN(size, self->msg_sz);
|
||||
out_sz = stream_p->read(self->sock, buf, sz, errcode);
|
||||
if (out_sz == 0 || out_sz == MP_STREAM_ERROR) {
|
||||
return out_sz;
|
||||
}
|
||||
|
||||
sz = out_sz;
|
||||
for (byte *p = buf; sz--; p++) {
|
||||
*p ^= self->mask[self->mask_pos++ & 3];
|
||||
}
|
||||
|
||||
self->msg_sz -= out_sz;
|
||||
if (self->msg_sz == 0) {
|
||||
byte last_state;
|
||||
no_payload:
|
||||
last_state = self->state;
|
||||
self->state = FRAME_HEADER;
|
||||
self->to_recv = 2;
|
||||
self->mask_pos = 0;
|
||||
self->buf_pos = 0;
|
||||
|
||||
// Handle control frame
|
||||
if (last_state == CONTROL) {
|
||||
byte frame_type = self->last_flags & FRAME_OPCODE_MASK;
|
||||
if (frame_type == FRAME_CLOSE) {
|
||||
static char close_resp[2] = {0x88, 0};
|
||||
int err;
|
||||
websocket_write(self_in, close_resp, sizeof(close_resp), &err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DEBUG_printf("Finished receiving ctrl message %x, ignoring\n", self->last_flags);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_sz != 0) {
|
||||
return out_sz;
|
||||
}
|
||||
// Empty (data) frame received is not EOF
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
assert(size < 0x10000);
|
||||
byte header[4] = {0x80 | (self->opts & FRAME_OPCODE_MASK)};
|
||||
int hdr_sz;
|
||||
if (size < 126) {
|
||||
header[1] = size;
|
||||
hdr_sz = 2;
|
||||
} else {
|
||||
header[1] = 126;
|
||||
header[2] = size >> 8;
|
||||
header[3] = size & 0xff;
|
||||
hdr_sz = 4;
|
||||
}
|
||||
|
||||
mp_obj_t dest[3];
|
||||
if (self->opts & BLOCKING_WRITE) {
|
||||
mp_load_method(self->sock, MP_QSTR_setblocking, dest);
|
||||
dest[2] = mp_const_true;
|
||||
mp_call_method_n_kw(1, 0, dest);
|
||||
}
|
||||
|
||||
mp_uint_t out_sz = mp_stream_write_exactly(self->sock, header, hdr_sz, errcode);
|
||||
if (*errcode == 0) {
|
||||
out_sz = mp_stream_write_exactly(self->sock, buf, size, errcode);
|
||||
}
|
||||
|
||||
if (self->opts & BLOCKING_WRITE) {
|
||||
dest[2] = mp_const_false;
|
||||
mp_call_method_n_kw(1, 0, dest);
|
||||
}
|
||||
|
||||
if (*errcode != 0) {
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
return out_sz;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t websocket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
switch (request) {
|
||||
case MP_STREAM_CLOSE:
|
||||
// TODO: Send close signaling to the other side, otherwise it's
|
||||
// abrupt close (connection abort).
|
||||
mp_stream_close(self->sock);
|
||||
return 0;
|
||||
case MP_STREAM_GET_DATA_OPTS:
|
||||
return self->ws_flags & FRAME_OPCODE_MASK;
|
||||
case MP_STREAM_SET_DATA_OPTS: {
|
||||
int cur = self->opts & FRAME_OPCODE_MASK;
|
||||
self->opts = (self->opts & ~FRAME_OPCODE_MASK) | (arg & FRAME_OPCODE_MASK);
|
||||
return cur;
|
||||
}
|
||||
default:
|
||||
*errcode = MP_EINVAL;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_stream_ioctl_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t websocket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.read = websocket_read,
|
||||
.write = websocket_write,
|
||||
.ioctl = websocket_ioctl,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t websocket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_websocket,
|
||||
.make_new = websocket_make_new,
|
||||
.protocol = &websocket_stream_p,
|
||||
.locals_dict = (void *)&websocket_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t websocket_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_websocket) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&websocket_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(websocket_module_globals, websocket_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_websocket = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&websocket_module_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_WEBSOCKET
|
@ -1,14 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#ifndef MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H
|
||||
#define MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H
|
||||
|
||||
#define FRAME_OPCODE_MASK 0x0f
|
||||
enum {
|
||||
FRAME_CONT, FRAME_TXT, FRAME_BIN,
|
||||
FRAME_CLOSE = 0x8, FRAME_PING, FRAME_PONG
|
||||
};
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_MODWEBSOCKET_H
|
@ -1 +1 @@
|
||||
Subproject commit ef65415b5503ae71cc0a9064197f2e3fa5365d74
|
||||
Subproject commit e3bf07cabb728ecfa2b78ea5e468179f94dbf933
|
@ -11,6 +11,7 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objarray.h"
|
||||
#include "py/stream.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
@ -39,6 +40,20 @@ int mp_uos_dupterm_rx_chr(void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM
|
||||
if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) {
|
||||
byte buf[1];
|
||||
int errcode = 0;
|
||||
const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx]));
|
||||
mp_uint_t out_sz = stream_p->read(MP_STATE_VM(dupterm_objs[idx]), buf, 1, &errcode);
|
||||
if (errcode == 0 && out_sz != 0) {
|
||||
return buf[0];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
byte buf[1];
|
||||
@ -79,6 +94,16 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
|
||||
if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM
|
||||
if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) {
|
||||
int errcode = 0;
|
||||
const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx]));
|
||||
stream_p->write(MP_STATE_VM(dupterm_objs[idx]), str, len, &errcode);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_stream_write(MP_STATE_VM(dupterm_objs[idx]), str, len, MP_STREAM_RW_WRITE);
|
||||
|
@ -207,7 +207,7 @@ mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) {
|
||||
mp_vfs_mount_t *vfs = NULL;
|
||||
size_t mnt_len;
|
||||
const char *mnt_str = NULL;
|
||||
if (MP_OBJ_IS_STR(mnt_in)) {
|
||||
if (mp_obj_is_str(mnt_in)) {
|
||||
mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len);
|
||||
}
|
||||
for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) {
|
||||
@ -250,7 +250,7 @@ mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
||||
|
||||
#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX
|
||||
// If the file is an integer then delegate straight to the POSIX handler
|
||||
if (MP_OBJ_IS_SMALL_INT(args[ARG_file].u_obj)) {
|
||||
if (mp_obj_is_small_int(args[ARG_file].u_obj)) {
|
||||
return mp_vfs_posix_file_open(&mp_type_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj);
|
||||
}
|
||||
#endif
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#if _MAX_SS == _MIN_SS
|
||||
#define SECSIZE(fs) (_MIN_SS)
|
||||
#if FF_MAX_SS == FF_MIN_SS
|
||||
#define SECSIZE(fs) (FF_MIN_SS)
|
||||
#else
|
||||
#define SECSIZE(fs) ((fs)->ssize)
|
||||
#endif
|
||||
@ -84,7 +84,7 @@ STATIC void verify_fs_writable(fs_user_mount_t *vfs) {
|
||||
}
|
||||
}
|
||||
|
||||
#if _FS_REENTRANT
|
||||
#if FF_FS_REENTRANT
|
||||
STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) {
|
||||
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
// f_umount only needs to be called to release the sync object
|
||||
@ -99,8 +99,11 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
|
||||
fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL));
|
||||
|
||||
// make the filesystem
|
||||
uint8_t working_buf[_MAX_SS];
|
||||
uint8_t working_buf[FF_MAX_SS];
|
||||
FRESULT res = f_mkfs(&vfs->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||
if (res == FR_MKFS_ABORTED) { // Probably doesn't support FAT16
|
||||
res = f_mkfs(&vfs->fatfs, FM_FAT32, 0, working_buf, sizeof(working_buf));
|
||||
}
|
||||
if (res != FR_OK) {
|
||||
mp_raise_OSError(fresult_to_errno_table[res]);
|
||||
}
|
||||
@ -377,7 +380,7 @@ STATIC mp_obj_t fat_vfs_statvfs(mp_obj_t vfs_in, mp_obj_t path_in) {
|
||||
t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree
|
||||
t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail
|
||||
t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags
|
||||
t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax
|
||||
t->items[9] = MP_OBJ_NEW_SMALL_INT(FF_MAX_LFN); // f_namemax
|
||||
|
||||
return MP_OBJ_FROM_PTR(t);
|
||||
}
|
||||
@ -397,7 +400,7 @@ STATIC mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs
|
||||
// check if we need to make the filesystem
|
||||
FRESULT res = (self->flags & FSUSER_NO_FILESYSTEM) ? FR_NO_FILESYSTEM : FR_OK;
|
||||
if (res == FR_NO_FILESYSTEM && mp_obj_is_true(mkfs)) {
|
||||
uint8_t working_buf[_MAX_SS];
|
||||
uint8_t working_buf[FF_MAX_SS];
|
||||
res = f_mkfs(&self->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf));
|
||||
}
|
||||
if (res != FR_OK) {
|
||||
@ -451,7 +454,7 @@ STATIC const mp_obj_property_t fat_vfs_label_obj = {
|
||||
#endif
|
||||
|
||||
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
||||
#if _FS_REENTRANT
|
||||
#if FF_FS_REENTRANT
|
||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&fat_vfs_del_obj) },
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
|
||||
|
@ -18,8 +18,8 @@
|
||||
#include "lib/oofatfs/diskio.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
|
||||
#if _MAX_SS == _MIN_SS
|
||||
#define SECSIZE(fs) (_MIN_SS)
|
||||
#if FF_MAX_SS == FF_MIN_SS
|
||||
#define SECSIZE(fs) (FF_MIN_SS)
|
||||
#else
|
||||
#define SECSIZE(fs) ((fs)->ssize)
|
||||
#endif
|
||||
@ -34,7 +34,7 @@ STATIC fs_user_mount_t *disk_get_device(void *bdev) {
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read(
|
||||
bdev_t pdrv, /* Physical drive */
|
||||
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE *buff, /* Data buffer to store read data */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
UINT count /* Number of sectors to read (1..128) */
|
||||
@ -74,7 +74,7 @@ DRESULT disk_read(
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_write(
|
||||
bdev_t pdrv, /* Physical drive */
|
||||
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
UINT count /* Number of sectors to write (1..128) */
|
||||
@ -120,8 +120,8 @@ DRESULT disk_write(
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl(
|
||||
bdev_t pdrv, /* Physical drive */
|
||||
BYTE cmd, /* Control code */
|
||||
bdev_t pdrv, /* Physical drive nmuber (0..) */
|
||||
BYTE cmd, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
) {
|
||||
fs_user_mount_t *vfs = disk_get_device(pdrv);
|
||||
@ -198,7 +198,7 @@ DRESULT disk_ioctl(
|
||||
} else {
|
||||
*((WORD *)buff) = out_value;
|
||||
}
|
||||
#if _MAX_SS != _MIN_SS
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
// need to store ssize because we use it in disk_read/disk_write
|
||||
vfs->fatfs.ssize = *((WORD *)buff);
|
||||
#endif
|
||||
|
@ -110,7 +110,7 @@ STATIC mp_obj_t vfs_posix_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode
|
||||
&& (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL || strchr(mode, '+') != NULL)) {
|
||||
mp_raise_OSError(MP_EROFS);
|
||||
}
|
||||
if (!MP_OBJ_IS_SMALL_INT(path_in)) {
|
||||
if (!mp_obj_is_small_int(path_in)) {
|
||||
path_in = vfs_posix_get_path_obj(self, path_in);
|
||||
}
|
||||
return mp_vfs_posix_file_open(&mp_type_textio, path_in, mode_in);
|
||||
|
@ -74,7 +74,7 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_
|
||||
|
||||
mp_obj_t fid = file_in;
|
||||
|
||||
if (MP_OBJ_IS_SMALL_INT(fid)) {
|
||||
if (mp_obj_is_small_int(fid)) {
|
||||
o->fd = MP_OBJ_SMALL_INT_VALUE(fid);
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
#define NETUTILS_IPV4ADDR_BUFSIZE 4
|
||||
|
||||
#define NETUTILS_TRACE_IS_TX (0x0001)
|
||||
#define NETUTILS_TRACE_PAYLOAD (0x0002)
|
||||
#define NETUTILS_TRACE_NEWLINE (0x0004)
|
||||
|
||||
typedef enum _netutils_endian_t {
|
||||
NETUTILS_LITTLE,
|
||||
NETUTILS_BIG,
|
||||
@ -47,4 +51,6 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian
|
||||
// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes).
|
||||
mp_uint_t netutils_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian_t endian);
|
||||
|
||||
void netutils_ethernet_trace(const mp_print_t *print, size_t len, const uint8_t *buf, unsigned int flags);
|
||||
|
||||
#endif // MICROPY_INCLUDED_LIB_NETUTILS_NETUTILS_H
|
||||
|
170
lib/netutils/trace.c
Normal file
170
lib/netutils/trace.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 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 "py/mphal.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
static uint32_t get_be16(const uint8_t *buf) {
|
||||
return buf[0] << 8 | buf[1];
|
||||
}
|
||||
|
||||
static uint32_t get_be32(const uint8_t *buf) {
|
||||
return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
|
||||
}
|
||||
|
||||
static void dump_hex_bytes(const mp_print_t *print, size_t len, const uint8_t *buf) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
mp_printf(print, " %02x", buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *ethertype_str(uint16_t type) {
|
||||
// A value between 0x0000 - 0x05dc (inclusive) indicates a length, not type
|
||||
switch (type) {
|
||||
case 0x0800:
|
||||
return "IPv4";
|
||||
case 0x0806:
|
||||
return "ARP";
|
||||
case 0x86dd:
|
||||
return "IPv6";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void netutils_ethernet_trace(const mp_print_t *print, size_t len, const uint8_t *buf, unsigned int flags) {
|
||||
mp_printf(print, "[% 8d] ETH%cX len=%u", mp_hal_ticks_ms(), flags & NETUTILS_TRACE_IS_TX ? 'T' : 'R', len);
|
||||
mp_printf(print, " dst=%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
|
||||
mp_printf(print, " src=%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
||||
|
||||
const char *ethertype = ethertype_str(buf[12] << 8 | buf[13]);
|
||||
if (ethertype) {
|
||||
mp_printf(print, " type=%s", ethertype);
|
||||
} else {
|
||||
mp_printf(print, " type=0x%04x", buf[12] << 8 | buf[13]);
|
||||
}
|
||||
if (len > 14) {
|
||||
len -= 14;
|
||||
buf += 14;
|
||||
if (buf[-2] == 0x08 && buf[-1] == 0x00 && buf[0] == 0x45) {
|
||||
// IPv4 packet
|
||||
len = get_be16(buf + 2);
|
||||
mp_printf(print, " srcip=%u.%u.%u.%u dstip=%u.%u.%u.%u",
|
||||
buf[12], buf[13], buf[14], buf[15],
|
||||
buf[16], buf[17], buf[18], buf[19]);
|
||||
uint8_t prot = buf[9];
|
||||
buf += 20;
|
||||
len -= 20;
|
||||
if (prot == 6) {
|
||||
// TCP packet
|
||||
uint16_t srcport = get_be16(buf);
|
||||
uint16_t dstport = get_be16(buf + 2);
|
||||
uint32_t seqnum = get_be32(buf + 4);
|
||||
uint32_t acknum = get_be32(buf + 8);
|
||||
uint16_t dataoff_flags = get_be16(buf + 12);
|
||||
uint16_t winsz = get_be16(buf + 14);
|
||||
mp_printf(print, " TCP srcport=%u dstport=%u seqnum=%u acknum=%u dataoff=%u flags=%x winsz=%u",
|
||||
srcport, dstport, (unsigned)seqnum, (unsigned)acknum, dataoff_flags >> 12, dataoff_flags & 0x1ff, winsz);
|
||||
buf += 20;
|
||||
len -= 20;
|
||||
if (dataoff_flags >> 12 > 5) {
|
||||
mp_printf(print, " opts=");
|
||||
size_t opts_len = ((dataoff_flags >> 12) - 5) * 4;
|
||||
dump_hex_bytes(print, opts_len, buf);
|
||||
buf += opts_len;
|
||||
len -= opts_len;
|
||||
}
|
||||
} else if (prot == 17) {
|
||||
// UDP packet
|
||||
uint16_t srcport = get_be16(buf);
|
||||
uint16_t dstport = get_be16(buf + 2);
|
||||
mp_printf(print, " UDP srcport=%u dstport=%u", srcport, dstport);
|
||||
len = get_be16(buf + 4);
|
||||
buf += 8;
|
||||
if ((srcport == 67 && dstport == 68) || (srcport == 68 && dstport == 67)) {
|
||||
// DHCP
|
||||
if (srcport == 67) {
|
||||
mp_printf(print, " DHCPS");
|
||||
} else {
|
||||
mp_printf(print, " DHCPC");
|
||||
}
|
||||
dump_hex_bytes(print, 12 + 16 + 16 + 64, buf);
|
||||
size_t n = 12 + 16 + 16 + 64 + 128;
|
||||
len -= n;
|
||||
buf += n;
|
||||
mp_printf(print, " opts:");
|
||||
switch (buf[6]) {
|
||||
case 1:
|
||||
mp_printf(print, " DISCOVER");
|
||||
break;
|
||||
case 2:
|
||||
mp_printf(print, " OFFER");
|
||||
break;
|
||||
case 3:
|
||||
mp_printf(print, " REQUEST");
|
||||
break;
|
||||
case 4:
|
||||
mp_printf(print, " DECLINE");
|
||||
break;
|
||||
case 5:
|
||||
mp_printf(print, " ACK");
|
||||
break;
|
||||
case 6:
|
||||
mp_printf(print, " NACK");
|
||||
break;
|
||||
case 7:
|
||||
mp_printf(print, " RELEASE");
|
||||
break;
|
||||
case 8:
|
||||
mp_printf(print, " INFORM");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Non-UDP packet
|
||||
mp_printf(print, " prot=%u", prot);
|
||||
}
|
||||
} else if (buf[-2] == 0x86 && buf[-1] == 0xdd && (buf[0] >> 4) == 6) {
|
||||
// IPv6 packet
|
||||
uint32_t h = get_be32(buf);
|
||||
uint16_t l = get_be16(buf + 4);
|
||||
mp_printf(print, " tclass=%u flow=%u len=%u nexthdr=%u hoplimit=%u", (unsigned)((h >> 20) & 0xff), (unsigned)(h & 0xfffff), l, buf[6], buf[7]);
|
||||
mp_printf(print, " srcip=");
|
||||
dump_hex_bytes(print, 16, buf + 8);
|
||||
mp_printf(print, " dstip=");
|
||||
dump_hex_bytes(print, 16, buf + 24);
|
||||
buf += 40;
|
||||
len -= 40;
|
||||
}
|
||||
if (flags & NETUTILS_TRACE_PAYLOAD) {
|
||||
mp_printf(print, " data=");
|
||||
dump_hex_bytes(print, len, buf);
|
||||
}
|
||||
}
|
||||
if (flags & NETUTILS_TRACE_NEWLINE) {
|
||||
mp_printf(print, "\n");
|
||||
}
|
||||
}
|
@ -13,8 +13,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
@ -47,11 +45,11 @@ DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff);
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define IOCTL_INIT 5
|
||||
#define IOCTL_STATUS 6
|
||||
|
||||
|
3814
lib/oofatfs/ff.c
3814
lib/oofatfs/ff.c
File diff suppressed because it is too large
Load Diff
220
lib/oofatfs/ff.h
220
lib/oofatfs/ff.h
@ -3,10 +3,10 @@
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT file system module R0.12b /
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2016, ChaN, all right reserved.
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
@ -19,81 +19,93 @@
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 68020 /* Revision ID */
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include FFCONF_H /* FatFs configuration options */
|
||||
|
||||
/* This type MUST be 8-bit */
|
||||
typedef uint8_t BYTE;
|
||||
|
||||
/* These types MUST be 16-bit */
|
||||
typedef int16_t SHORT;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint16_t WCHAR;
|
||||
|
||||
/* These types MUST be 16-bit or 32-bit */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types MUST be 32-bit */
|
||||
typedef int32_t LONG;
|
||||
typedef uint32_t DWORD;
|
||||
|
||||
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
|
||||
typedef uint64_t QWORD;
|
||||
|
||||
#include FFCONF_H /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
|
||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PT(fs) (fs->part) /* Get partition index */
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PT(fs) 0 /* Find first valid partition or in SFD */
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
||||
#if _USE_LFN == 0
|
||||
#error _LFN_UNICODE must be 0 at non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if _FS_EXFAT
|
||||
#if _USE_LFN == 0
|
||||
#error LFN must be enabled when enable exFAT
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
@ -102,39 +114,39 @@ typedef DWORD FSIZE_t;
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
void *drv; // block device underlying this filesystem
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
BYTE part; // Partition: 0:Auto detect, 1-4:Forced partition
|
||||
#endif
|
||||
BYTE fs_type; /* File system type (0:N/A) */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if _MAX_SS != _MIN_SS
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _USE_LFN != 0
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if _FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if _FS_RPATH != 0
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if _FS_EXFAT
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
@ -146,52 +158,56 @@ typedef struct {
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (_FDID) */
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:got flagmented, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if _FS_EXFAT
|
||||
DWORD n_cont; /* Size of coutiguous part, clusters - 1 (valid when stat == 3) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0) */
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if _FS_LOCK != 0
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} _FDID;
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fprt is 0) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
@ -200,16 +216,16 @@ typedef struct {
|
||||
/* Directory object structure (FF_DIR) */
|
||||
|
||||
typedef struct {
|
||||
_FDID obj; /* Object identifier */
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if _USE_LFN != 0
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} FF_DIR;
|
||||
@ -223,11 +239,11 @@ typedef struct {
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if _USE_LFN != 0
|
||||
TCHAR altname[13]; /* Altenative file name */
|
||||
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[13]; /* File name */
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
@ -254,7 +270,7 @@ typedef enum {
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
@ -292,6 +308,7 @@ FRESULT f_mount (FATFS* fs); /* Mount/Unm
|
||||
FRESULT f_umount (FATFS* fs); /* Unmount a logical drive */
|
||||
FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
@ -299,6 +316,8 @@ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
@ -311,26 +330,27 @@ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY && !_FS_NORTC
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (FATFS *fatfs, _SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (FATFS *fatfs, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
@ -377,4 +397,4 @@ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
#endif /* FF_DEFINED */
|
||||
|
@ -2,11 +2,11 @@
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* Original file from:
|
||||
* FatFs - FAT file system module configuration file R0.12a (C)ChaN, 2016
|
||||
* FatFs - FAT file system module configuration file R0.13c (C)ChaN, 2018
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-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
|
||||
@ -30,73 +30,72 @@
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 68020 /* Revision ID */
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_READONLY 0
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
|
||||
/ f_printf().
|
||||
#define FF_USE_STRFUNC 0
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
#define FF_USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 1
|
||||
#define FF_USE_FASTSEEK 1
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_EXPAND 0
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_CHMOD 1
|
||||
#define FF_USE_CHMOD 1
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_USE_LABEL
|
||||
#define _USE_LABEL (MICROPY_FATFS_USE_LABEL)
|
||||
#define FF_USE_LABEL (MICROPY_FATFS_USE_LABEL)
|
||||
#else
|
||||
#define _USE_LABEL 0
|
||||
#define FF_USE_LABEL 0
|
||||
#endif
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
@ -105,14 +104,13 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef MICROPY_FATFS_LFN_CODE_PAGE
|
||||
#define _CODE_PAGE (MICROPY_FATFS_LFN_CODE_PAGE)
|
||||
#define FF_CODE_PAGE MICROPY_FATFS_LFN_CODE_PAGE
|
||||
#else
|
||||
#define _CODE_PAGE 1
|
||||
#define FF_CODE_PAGE 437
|
||||
#endif
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
@ -134,59 +132,77 @@
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_ENABLE_LFN
|
||||
#define _USE_LFN (MICROPY_FATFS_ENABLE_LFN)
|
||||
#define FF_USE_LFN (MICROPY_FATFS_ENABLE_LFN)
|
||||
#else
|
||||
#define _USE_LFN 0
|
||||
#define FF_USE_LFN 0
|
||||
#endif
|
||||
#ifdef MICROPY_FATFS_MAX_LFN
|
||||
#define _MAX_LFN (MICROPY_FATFS_MAX_LFN)
|
||||
#define FF_MAX_LFN (MICROPY_FATFS_MAX_LFN)
|
||||
#else
|
||||
#define _MAX_LFN 255
|
||||
#define FF_MAX_LFN 255
|
||||
#endif
|
||||
/* The _USE_LFN switches the support of long file name (LFN).
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable support of LFN. _MAX_LFN has no effect.
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
||||
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
||||
/ It should be set 255 to support full featured LFN operations.
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree(), must be added to the project. */
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0
|
||||
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
|
||||
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
||||
/ This option also affects behavior of string I/O functions. */
|
||||
|
||||
|
||||
#define _STRF_ENCODE 3
|
||||
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
|
||||
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM
|
||||
/ 1: UTF-16LE
|
||||
/ 2: UTF-16BE
|
||||
/ 3: UTF-8
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_RPATH
|
||||
#define _FS_RPATH (MICROPY_FATFS_RPATH)
|
||||
#define FF_FS_RPATH (MICROPY_FATFS_RPATH)
|
||||
#else
|
||||
#define _FS_RPATH 0
|
||||
#define FF_FS_RPATH 0
|
||||
#endif
|
||||
/* This option configures support of relative path.
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
@ -198,53 +214,58 @@
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* _STR_VOLUME_ID switches string support of volume ID.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
|
||||
/ the drive ID strings are: A-Z and 0-9. */
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_MULTI_PARTITION
|
||||
#define _MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION)
|
||||
#define FF_MULTI_PARTITION (MICROPY_FATFS_MULTI_PARTITION)
|
||||
#else
|
||||
#define _MULTI_PARTITION 0
|
||||
#define FF_MULTI_PARTITION 0
|
||||
#endif
|
||||
/* This option switches support of multi-partition on a physical drive.
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When multi-partition is enabled (1), each logical drive number can be bound to
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
#define FF_MIN_SS 512
|
||||
#ifdef MICROPY_FATFS_MAX_SS
|
||||
#define _MAX_SS (MICROPY_FATFS_MAX_SS)
|
||||
#define FF_MAX_SS (MICROPY_FATFS_MAX_SS)
|
||||
#else
|
||||
#define _MAX_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
#endif
|
||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
|
||||
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define _USE_TRIM 0
|
||||
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define _FS_NOFSINFO 0
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
@ -261,44 +282,44 @@
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 1
|
||||
#define FF_FS_TINY 1
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the file system object (FATFS) is used for the file data transfer. */
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_EXFAT
|
||||
#define _FS_EXFAT (MICROPY_FATFS_EXFAT)
|
||||
#define FF_FS_EXFAT (MICROPY_FATFS_EXFAT)
|
||||
#else
|
||||
#define _FS_EXFAT 0
|
||||
#define FF_FS_EXFAT 0
|
||||
#endif
|
||||
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
||||
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards C89 compatibility. */
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_NORTC
|
||||
#define _FS_NORTC (MICROPY_FATFS_NORTC)
|
||||
#define FF_FS_NORTC (MICROPY_FATFS_NORTC)
|
||||
#else
|
||||
#define _FS_NORTC 0
|
||||
#define FF_FS_NORTC 0
|
||||
#endif
|
||||
#define _NORTC_MON 1
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2016
|
||||
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to get current time form real-time clock. _NORTC_MON,
|
||||
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define _FS_LOCK 0
|
||||
/* The option _FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
@ -309,41 +330,40 @@
|
||||
|
||||
|
||||
#ifdef MICROPY_FATFS_REENTRANT
|
||||
#define _FS_REENTRANT (MICROPY_FATFS_REENTRANT)
|
||||
#define FF_FS_REENTRANT (MICROPY_FATFS_REENTRANT)
|
||||
#else
|
||||
#define _FS_REENTRANT 0
|
||||
#define FF_FS_REENTRANT 0
|
||||
#endif
|
||||
|
||||
// milliseconds
|
||||
#ifdef MICROPY_FATFS_TIMEOUT
|
||||
#define _FS_TIMEOUT (MICROPY_FATFS_TIMEOUT)
|
||||
#define FF_FS_TIMEOUT (MICROPY_FATFS_TIMEOUT)
|
||||
#else
|
||||
#define _FS_TIMEOUT 1000
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#endif
|
||||
|
||||
#ifdef MICROPY_FATFS_SYNC_T
|
||||
#define _SYNC_t MICROPY_FATFS_SYNC_T
|
||||
#define FF_SYNC_t MICROPY_FATFS_SYNC_T
|
||||
#else
|
||||
#define _SYNC_t HANDLE
|
||||
#define FF_SYNC_t HANDLE
|
||||
#endif
|
||||
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
/* #include <windows.h> // O/S definitions */
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
@ -1,33 +1,46 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
|
||||
/* (SBCS code pages) */
|
||||
/* Unicode handling functions for FatFs R0.13c */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S.
|
||||
/ 720 Arabic
|
||||
/ 737 Greek
|
||||
/ 771 KBL
|
||||
/ 775 Baltic
|
||||
/ 850 Latin 1
|
||||
/ 852 Latin 2
|
||||
/ 855 Cyrillic
|
||||
/ 857 Turkish
|
||||
/ 860 Portuguese
|
||||
/ 861 Icelandic
|
||||
/ 862 Hebrew
|
||||
/ 863 Canadian French
|
||||
/ 864 Arabic
|
||||
/ 865 Nordic
|
||||
/ 866 Russian
|
||||
/ 869 Greek 2
|
||||
/* This module will occupy a huge memory in the .const section when the /
|
||||
/ FatFs is configured for LFN with DBCS. If the system has any Unicode /
|
||||
/ utilitiy for the code conversion, this module should be modified to use /
|
||||
/ that function to avoid silly memory consumption. /
|
||||
/-------------------------------------------------------------------------*/
|
||||
/*
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
/
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
*/
|
||||
|
||||
#include "../ff.h"
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */
|
||||
|
||||
#if FF_DEFINED != 86604 /* Revision ID */
|
||||
#error Wrong include file (ff.h).
|
||||
#endif
|
||||
|
||||
#define MERGE2(a, b) a ## b
|
||||
#define CVTBL(tbl, cp) MERGE2(tbl, cp)
|
||||
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Code Conversion Tables */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 437 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc437[] = { /* CP437(U.S.) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -37,11 +50,9 @@ const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 720 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc720[] = { /* CP720(Arabic) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
@ -51,11 +62,9 @@ const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 737 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc737[] = { /* CP737(Greek) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
@ -65,11 +74,9 @@ const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 771
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 771 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc771[] = { /* CP771(KBL) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
@ -79,11 +86,9 @@ const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 775 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc775[] = { /* CP775(Baltic) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
@ -93,11 +98,9 @@ const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 850 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc850[] = { /* CP850(Latin 1) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -107,11 +110,9 @@ const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 852 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc852[] = { /* CP852(Latin 2) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
@ -121,11 +122,9 @@ const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 855 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc855[] = { /* CP855(Cyrillic) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
@ -135,11 +134,9 @@ const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 857 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc857[] = { /* CP857(Turkish) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -149,11 +146,9 @@ const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 860
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 860 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc860[] = { /* CP860(Portuguese) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
||||
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -163,11 +158,9 @@ const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 861
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 861 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc861[] = { /* CP861(Icelandic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -177,11 +170,9 @@ const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 862 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc862[] = { /* CP862(Hebrew) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
@ -191,11 +182,9 @@ const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 863
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 863 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc863[] = { /* CP863(Canadian French) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
||||
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
||||
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
||||
@ -205,11 +194,9 @@ const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 864
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 864 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc864[] = { /* CP864(Arabic) to Unicode conversion table */
|
||||
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
||||
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
||||
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
||||
@ -219,11 +206,9 @@ const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
||||
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
||||
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 865
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 865 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc865[] = { /* CP865(Nordic) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
||||
@ -233,11 +218,9 @@ const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 866 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc866[] = { /* CP866(Russian) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
@ -247,11 +230,9 @@ const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 869
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
||||
#endif
|
||||
#if FF_CODE_PAGE == 869 || FF_CODE_PAGE == 0
|
||||
static const WCHAR uc869[] = { /* CP869(Greek 2) to Unicode conversion table */
|
||||
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
||||
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
||||
@ -261,36 +242,32 @@ const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
||||
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
||||
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !_TBLDEF || !_USE_LFN
|
||||
#error This file is not needed at current configuration. Remove from the project.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR chr, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for static code page configuration */
|
||||
/* SBCS fixed code page */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
WCHAR c = 0;
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (chr < 0x80) { /* ASCII */
|
||||
c = chr;
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEM code to Unicode */
|
||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
||||
|
||||
} else { /* Unicode to OEM code */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (chr == Tbl[c]) break;
|
||||
}
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
for (c = 0; c < 0x80 && uni != p[c]; c++) ;
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
@ -298,56 +275,314 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Returns upper converted character */
|
||||
WCHAR chr /* Unicode character to be upper converted (BMP only) */
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
/* Compressed upper conversion table */
|
||||
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
||||
WCHAR c = 0;
|
||||
const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it a valid code page? */
|
||||
if (oem < 0x100) c = p[oem - 0x80];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for static code page configuration */
|
||||
/* DBCS fixed code page */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE >= 900
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000 && cp == FF_CODE_PAGE) { /* Is it in BMP and valid code page? */
|
||||
uc = (WCHAR)uni;
|
||||
p = CVTBL(uni2oem, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(uni2oem, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i = 0, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
if (cp == FF_CODE_PAGE) { /* Is it valid code page? */
|
||||
p = CVTBL(oem2uni, FF_CODE_PAGE);
|
||||
hi = sizeof CVTBL(oem2uni, FF_CODE_PAGE) / 4 - 1;
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (oem == p[i * 2]) break;
|
||||
if (oem > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* OEM <==> Unicode conversions for dynamic code page configuration */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#if FF_CODE_PAGE == 0
|
||||
|
||||
static const WORD cp_code[] = { 437, 720, 737, 771, 775, 850, 852, 855, 857, 860, 861, 862, 863, 864, 865, 866, 869, 0};
|
||||
static const WCHAR* const cp_table[] = {uc437, uc720, uc737, uc771, uc775, uc850, uc852, uc855, uc857, uc860, uc861, uc862, uc863, uc864, uc865, uc866, uc869, 0};
|
||||
|
||||
|
||||
WCHAR ff_uni2oem ( /* Returns OEM code character, zero on error */
|
||||
DWORD uni, /* UTF-16 encoded character to be converted */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0, uc;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (uni < 0x80) { /* ASCII? */
|
||||
c = (WCHAR)uni;
|
||||
|
||||
} else { /* Non-ASCII */
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WCHAR)uni;
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get conversion table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it valid code page ? */
|
||||
for (c = 0; c < 0x80 && uc != p[c]; c++) ; /* Find OEM code in the table */
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) { /* Get conversion table */
|
||||
case 932 : p = uni2oem932; hi = sizeof uni2oem932 / 4 - 1; break;
|
||||
case 936 : p = uni2oem936; hi = sizeof uni2oem936 / 4 - 1; break;
|
||||
case 949 : p = uni2oem949; hi = sizeof uni2oem949 / 4 - 1; break;
|
||||
case 950 : p = uni2oem950; hi = sizeof uni2oem950 / 4 - 1; break;
|
||||
}
|
||||
if (p) { /* Is it valid code page? */
|
||||
li = 0;
|
||||
for (n = 16; n; n--) { /* Find OEM code */
|
||||
i = li + (hi - li) / 2;
|
||||
if (uc == p[i * 2]) break;
|
||||
if (uc > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_oem2uni ( /* Returns Unicode character, zero on error */
|
||||
WCHAR oem, /* OEM code to be converted (DBC if >=0x100) */
|
||||
WORD cp /* Code page for the conversion */
|
||||
)
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR c = 0;
|
||||
UINT i, n, li, hi;
|
||||
|
||||
|
||||
if (oem < 0x80) { /* ASCII? */
|
||||
c = oem;
|
||||
|
||||
} else { /* Extended char */
|
||||
p = 0;
|
||||
if (cp < 900) { /* SBCS */
|
||||
for (i = 0; cp_code[i] != 0 && cp_code[i] != cp; i++) ; /* Get table */
|
||||
p = cp_table[i];
|
||||
if (p) { /* Is it a valid CP ? */
|
||||
if (oem < 0x100) c = p[oem - 0x80];
|
||||
}
|
||||
} else { /* DBCS */
|
||||
switch (cp) {
|
||||
case 932 : p = oem2uni932; hi = sizeof oem2uni932 / 4 - 1; break;
|
||||
case 936 : p = oem2uni936; hi = sizeof oem2uni936 / 4 - 1; break;
|
||||
case 949 : p = oem2uni949; hi = sizeof oem2uni949 / 4 - 1; break;
|
||||
case 950 : p = oem2uni950; hi = sizeof oem2uni950 / 4 - 1; break;
|
||||
}
|
||||
if (p) {
|
||||
li = 0;
|
||||
for (n = 16; n; n--) {
|
||||
i = li + (hi - li) / 2;
|
||||
if (oem == p[i * 2]) break;
|
||||
if (oem > p[i * 2]) {
|
||||
li = i;
|
||||
} else {
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
if (n != 0) c = p[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode up-case conversion */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
DWORD ff_wtoupper ( /* Returns up-converted code point */
|
||||
DWORD uni /* Unicode code point to be up-converted */
|
||||
)
|
||||
{
|
||||
const WORD *p;
|
||||
WORD uc, bc, nc, cmd;
|
||||
static const WORD cvt1[] = { /* Compressed up conversion table for U+0000 - U+0FFF */
|
||||
/* Basic Latin */
|
||||
0x0061,0x031A,
|
||||
/* Latin-1 Supplement */
|
||||
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
||||
0x00E0,0x0317,
|
||||
0x00F8,0x0307,
|
||||
0x00FF,0x0001,0x0178,
|
||||
/* Latin Extended-A */
|
||||
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
||||
0x0100,0x0130,
|
||||
0x0132,0x0106,
|
||||
0x0139,0x0110,
|
||||
0x014A,0x012E,
|
||||
0x0179,0x0106,
|
||||
/* Latin Extended-B */
|
||||
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
||||
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
||||
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
||||
0x01CD,0x0110,
|
||||
0x01DD,0x0001,0x018E,
|
||||
0x01DE,0x0112,
|
||||
0x01F3,0x0003,0x01F1,0x01F4,0x01F4,
|
||||
0x01F8,0x0128,
|
||||
0x0222,0x0112,
|
||||
0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241,
|
||||
0x0246,0x010A,
|
||||
/* IPA Extensions */
|
||||
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
||||
/* Greek, Coptic */
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF,
|
||||
0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A,
|
||||
0x03B1,0x0311,
|
||||
0x03C2,0x0002,0x03A3,0x03A3,
|
||||
0x03C4,0x0308,
|
||||
0x03CC,0x0003,0x038C,0x038E,0x038F,
|
||||
0x03D8,0x0118,
|
||||
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
||||
/* Cyrillic */
|
||||
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
||||
0x0430,0x0320,
|
||||
0x0450,0x0710,
|
||||
0x0460,0x0122,
|
||||
0x048A,0x0136,
|
||||
0x04C1,0x010E,
|
||||
0x04CF,0x0001,0x04C0,
|
||||
0x04D0,0x0144,
|
||||
/* Armenian */
|
||||
0x0561,0x0426,
|
||||
|
||||
0x0000
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
||||
static const WORD cvt2[] = { /* Compressed up conversion table for U+1000 - U+FFFF */
|
||||
/* Phonetic Extensions */
|
||||
0x1D7D,0x0001,0x2C63,
|
||||
/* Latin Extended Additional */
|
||||
0x1E00,0x0196, 0x1EA0,0x015A,
|
||||
0x1E00,0x0196,
|
||||
0x1EA0,0x015A,
|
||||
/* Greek Extended */
|
||||
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
||||
0x1F00,0x0608,
|
||||
0x1F10,0x0606,
|
||||
0x1F20,0x0608,
|
||||
0x1F30,0x0608,
|
||||
0x1F40,0x0606,
|
||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F,
|
||||
0x1F60,0x0608,
|
||||
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
||||
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
|
||||
0x1F80,0x0608,
|
||||
0x1F90,0x0608,
|
||||
0x1FA0,0x0608,
|
||||
0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
||||
0x1FCC,0x0001,0x1FC3,
|
||||
0x1FD0,0x0602,
|
||||
0x1FE0,0x0602,
|
||||
0x1FE5,0x0001,0x1FEC,
|
||||
0x1FF3,0x0001,0x1FFC,
|
||||
/* Letterlike Symbols */
|
||||
0x214E,0x0001,0x2132,
|
||||
/* Number forms */
|
||||
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
||||
0x2170,0x0210,
|
||||
0x2184,0x0001,0x2183,
|
||||
/* Enclosed Alphanumerics */
|
||||
0x24D0,0x051A, 0x2C30,0x042F,
|
||||
0x24D0,0x051A,
|
||||
0x2C30,0x042F,
|
||||
/* Latin Extended-C */
|
||||
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
||||
0x2C60,0x0102,
|
||||
0x2C67,0x0106, 0x2C75,0x0102,
|
||||
/* Coptic */
|
||||
0x2C80,0x0164,
|
||||
/* Georgian Supplement */
|
||||
@ -355,33 +590,38 @@ WCHAR ff_wtoupper ( /* Returns upper converted character */
|
||||
/* Full-width */
|
||||
0xFF41,0x031A,
|
||||
|
||||
0x0000
|
||||
0x0000 /* EOT */
|
||||
};
|
||||
const WCHAR *p;
|
||||
WCHAR bc, nc, cmd;
|
||||
|
||||
|
||||
p = chr < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get block base */
|
||||
if (!bc || chr < bc) break;
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (chr < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
case 0: chr = p[chr - bc]; break; /* Table conversion */
|
||||
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
|
||||
case 2: chr -= 16; break; /* Shift -16 */
|
||||
case 3: chr -= 32; break; /* Shift -32 */
|
||||
case 4: chr -= 48; break; /* Shift -48 */
|
||||
case 5: chr -= 26; break; /* Shift -26 */
|
||||
case 6: chr += 8; break; /* Shift +8 */
|
||||
case 7: chr -= 80; break; /* Shift -80 */
|
||||
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
if (uni < 0x10000) { /* Is it in BMP? */
|
||||
uc = (WORD)uni;
|
||||
p = uc < 0x1000 ? cvt1 : cvt2;
|
||||
for (;;) {
|
||||
bc = *p++; /* Get the block base */
|
||||
if (bc == 0 || uc < bc) break; /* Not matched? */
|
||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
||||
if (uc < bc + nc) { /* In the block? */
|
||||
switch (cmd) {
|
||||
case 0: uc = p[uc - bc]; break; /* Table conversion */
|
||||
case 1: uc -= (uc - bc) & 1; break; /* Case pairs */
|
||||
case 2: uc -= 16; break; /* Shift -16 */
|
||||
case 3: uc -= 32; break; /* Shift -32 */
|
||||
case 4: uc -= 48; break; /* Shift -48 */
|
||||
case 5: uc -= 26; break; /* Shift -26 */
|
||||
case 6: uc += 8; break; /* Shift +8 */
|
||||
case 7: uc -= 80; break; /* Shift -80 */
|
||||
case 8: uc -= 0x1C60; break; /* Shift -0x1C60 */
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (cmd == 0) p += nc; /* Skip table if needed */
|
||||
}
|
||||
if (!cmd) p += nc;
|
||||
uni = uc;
|
||||
}
|
||||
|
||||
return chr;
|
||||
return uni;
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if FF_USE_LFN */
|
@ -1,17 +0,0 @@
|
||||
#include "../ff.h"
|
||||
|
||||
#if _USE_LFN != 0
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
|
||||
#include "cc932.c"
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#include "cc936.c"
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#include "cc949.c"
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#include "cc950.c"
|
||||
#else /* Single Byte Character-Set */
|
||||
#include "ccsbcs.c"
|
||||
#endif
|
||||
|
||||
#endif
|
34
lib/utils/gchelper.h
Normal file
34
lib/utils/gchelper.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H
|
||||
#define MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uintptr_t gc_helper_get_sp(void);
|
||||
uintptr_t gc_helper_get_regs_and_sp(uintptr_t *regs);
|
||||
|
||||
#endif // MICROPY_INCLUDED_LIB_UTILS_GCHELPER_H
|
61
lib/utils/gchelper_m0.s
Normal file
61
lib/utils/gchelper_m0.s
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
|
||||
.global gc_helper_get_regs_and_sp
|
||||
.type gc_helper_get_regs_and_sp, %function
|
||||
|
||||
@ uint gc_helper_get_regs_and_sp(r0=uint regs[10])
|
||||
gc_helper_get_regs_and_sp:
|
||||
@ store registers into given array
|
||||
str r4, [r0, #0]
|
||||
str r5, [r0, #4]
|
||||
str r6, [r0, #8]
|
||||
str r7, [r0, #12]
|
||||
mov r1, r8
|
||||
str r1, [r0, #16]
|
||||
mov r1, r9
|
||||
str r1, [r0, #20]
|
||||
mov r1, r10
|
||||
str r1, [r0, #24]
|
||||
mov r1, r11
|
||||
str r1, [r0, #28]
|
||||
mov r1, r12
|
||||
str r1, [r0, #32]
|
||||
mov r1, r13
|
||||
str r1, [r0, #36]
|
||||
|
||||
@ return the sp
|
||||
mov r0, sp
|
||||
bx lr
|
||||
|
||||
.size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp
|
67
lib/utils/gchelper_m3.s
Normal file
67
lib/utils/gchelper_m3.s
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.thumb
|
||||
|
||||
.section .text
|
||||
.align 2
|
||||
|
||||
.global gc_helper_get_sp
|
||||
.type gc_helper_get_sp, %function
|
||||
|
||||
@ uint gc_helper_get_sp(void)
|
||||
gc_helper_get_sp:
|
||||
@ return the sp
|
||||
mov r0, sp
|
||||
bx lr
|
||||
|
||||
.size gc_helper_get_sp, .-gc_helper_get_sp
|
||||
|
||||
|
||||
.global gc_helper_get_regs_and_sp
|
||||
.type gc_helper_get_regs_and_sp, %function
|
||||
|
||||
@ uint gc_helper_get_regs_and_sp(r0=uint regs[10])
|
||||
gc_helper_get_regs_and_sp:
|
||||
@ store registers into given array
|
||||
str r4, [r0], #4
|
||||
str r5, [r0], #4
|
||||
str r6, [r0], #4
|
||||
str r7, [r0], #4
|
||||
str r8, [r0], #4
|
||||
str r9, [r0], #4
|
||||
str r10, [r0], #4
|
||||
str r11, [r0], #4
|
||||
str r12, [r0], #4
|
||||
str r13, [r0], #4
|
||||
|
||||
@ return the sp
|
||||
mov r0, sp
|
||||
bx lr
|
||||
|
||||
.size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp
|
@ -29,7 +29,7 @@
|
||||
|
||||
#if MICROPY_KBD_EXCEPTION
|
||||
|
||||
int mp_interrupt_char;
|
||||
int mp_interrupt_char = -1;
|
||||
|
||||
void mp_hal_set_interrupt_char(int c) {
|
||||
if (c != -1) {
|
||||
|
@ -197,6 +197,7 @@ typedef struct _repl_t {
|
||||
// will be added later.
|
||||
// vstr_t line;
|
||||
bool cont_line;
|
||||
bool paste_mode;
|
||||
} repl_t;
|
||||
|
||||
repl_t repl;
|
||||
@ -207,6 +208,7 @@ STATIC int pyexec_friendly_repl_process_char(int c);
|
||||
void pyexec_event_repl_init(void) {
|
||||
MP_STATE_VM(repl_line) = vstr_new(32);
|
||||
repl.cont_line = false;
|
||||
repl.paste_mode = false;
|
||||
// no prompt before printing friendly REPL banner or entering raw REPL
|
||||
readline_init(MP_STATE_VM(repl_line), "");
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
@ -226,6 +228,7 @@ STATIC int pyexec_raw_repl_process_char(int c) {
|
||||
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
|
||||
vstr_reset(MP_STATE_VM(repl_line));
|
||||
repl.cont_line = false;
|
||||
repl.paste_mode = false;
|
||||
pyexec_friendly_repl_process_char(CHAR_CTRL_B);
|
||||
return 0;
|
||||
} else if (c == CHAR_CTRL_C) {
|
||||
@ -263,6 +266,32 @@ reset:
|
||||
}
|
||||
|
||||
STATIC int pyexec_friendly_repl_process_char(int c) {
|
||||
if (repl.paste_mode) {
|
||||
if (c == CHAR_CTRL_C) {
|
||||
// cancel everything
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
goto input_restart;
|
||||
} else if (c == CHAR_CTRL_D) {
|
||||
// end of input
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
goto input_restart;
|
||||
} else {
|
||||
// add char to buffer and echo
|
||||
vstr_add_byte(MP_STATE_VM(repl_line), c);
|
||||
if (c == '\r') {
|
||||
mp_hal_stdout_tx_str("\r\n=== ");
|
||||
} else {
|
||||
char buf[1] = {c};
|
||||
mp_hal_stdout_tx_strn(buf, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = readline_process_char(c);
|
||||
|
||||
if (!repl.cont_line) {
|
||||
@ -289,6 +318,12 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
vstr_clear(MP_STATE_VM(repl_line));
|
||||
return PYEXEC_FORCED_EXIT;
|
||||
} else if (ret == CHAR_CTRL_E) {
|
||||
// paste mode
|
||||
mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== ");
|
||||
vstr_reset(MP_STATE_VM(repl_line));
|
||||
repl.paste_mode = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@ -335,6 +370,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
|
||||
input_restart:
|
||||
vstr_reset(MP_STATE_VM(repl_line));
|
||||
repl.cont_line = false;
|
||||
repl.paste_mode = false;
|
||||
readline_init(MP_STATE_VM(repl_line), ">>> ");
|
||||
return 0;
|
||||
}
|
||||
@ -450,7 +486,7 @@ friendly_repl_reset:
|
||||
// do the user a favor and reenable interrupts.
|
||||
if (query_irq() == IRQ_STATE_DISABLED) {
|
||||
enable_irq(IRQ_STATE_ENABLED);
|
||||
mp_hal_stdout_tx_str("PYB: enabling IRQs\r\n");
|
||||
mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -541,20 +577,32 @@ int pyexec_file(const char *filename, pyexec_result_t *result) {
|
||||
return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME, result);
|
||||
}
|
||||
|
||||
int pyexec_file_if_exists(const char *filename, pyexec_result_t *result) {
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
if (mp_frozen_stat(filename) == MP_IMPORT_STAT_FILE) {
|
||||
return pyexec_frozen_module(filename, result);
|
||||
}
|
||||
#endif
|
||||
if (mp_import_stat(filename) != MP_IMPORT_STAT_FILE) {
|
||||
return 1; // success (no file is the same as an empty file executing without fail)
|
||||
}
|
||||
return pyexec_file(filename, result);
|
||||
}
|
||||
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
int pyexec_frozen_module(const char *name) {
|
||||
int pyexec_frozen_module(const char *name, pyexec_result_t *result) {
|
||||
void *frozen_data;
|
||||
int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data);
|
||||
|
||||
switch (frozen_type) {
|
||||
#if MICROPY_MODULE_FROZEN_STR
|
||||
case MP_FROZEN_STR:
|
||||
return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, NULL);
|
||||
return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0, result);
|
||||
#endif
|
||||
|
||||
#if MICROPY_MODULE_FROZEN_MPY
|
||||
case MP_FROZEN_MPY:
|
||||
return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, NULL);
|
||||
return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE, result);
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -54,7 +54,8 @@ extern int pyexec_system_exit;
|
||||
int pyexec_raw_repl(void);
|
||||
int pyexec_friendly_repl(void);
|
||||
int pyexec_file(const char *filename, pyexec_result_t *result);
|
||||
int pyexec_frozen_module(const char *name);
|
||||
int pyexec_file_if_exists(const char *filename, pyexec_result_t *result);
|
||||
int pyexec_frozen_module(const char *name, pyexec_result_t *result);
|
||||
void pyexec_event_repl_init(void);
|
||||
int pyexec_event_repl_process_char(int c);
|
||||
extern uint8_t pyexec_repl_active;
|
||||
|
@ -733,14 +733,6 @@ msgid ""
|
||||
"connection."
|
||||
msgstr ""
|
||||
|
||||
#: py/persistentcode.c
|
||||
msgid "Corrupt .mpy file"
|
||||
msgstr ""
|
||||
|
||||
#: py/emitglue.c
|
||||
msgid "Corrupt raw code"
|
||||
msgstr ""
|
||||
|
||||
#: ports/cxd56/common-hal/camera/Camera.c
|
||||
msgid "Could not initialize Camera"
|
||||
msgstr ""
|
||||
@ -2560,10 +2552,6 @@ msgstr ""
|
||||
msgid "can only have up to 4 parameters to Xtensa assembly"
|
||||
msgstr ""
|
||||
|
||||
#: py/persistentcode.c
|
||||
msgid "can only save bytecode"
|
||||
msgstr ""
|
||||
|
||||
#: py/objtype.c
|
||||
msgid "can't add special method to already-subclassed class"
|
||||
msgstr ""
|
||||
@ -3071,6 +3059,14 @@ msgstr ""
|
||||
msgid "identifier redefined as nonlocal"
|
||||
msgstr ""
|
||||
|
||||
#: py/persistentcode.c
|
||||
msgid "incompatible .mpy file"
|
||||
msgstr ""
|
||||
|
||||
#: py/persistentcode.c
|
||||
msgid "incompatible native .mpy architecture"
|
||||
msgstr ""
|
||||
|
||||
#: py/objstr.c
|
||||
msgid "incomplete format"
|
||||
msgstr ""
|
||||
@ -3190,6 +3186,10 @@ msgstr ""
|
||||
msgid "interval must be in range %s-%s"
|
||||
msgstr ""
|
||||
|
||||
#: py/compile.c
|
||||
msgid "invalid architecture"
|
||||
msgstr ""
|
||||
|
||||
#: lib/netutils/netutils.c
|
||||
msgid "invalid arguments"
|
||||
msgstr ""
|
||||
@ -3199,10 +3199,6 @@ msgstr ""
|
||||
msgid "invalid bits_per_pixel %d, must be, 1, 4, 8, 16, 24, or 32"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/modussl_axtls.c
|
||||
msgid "invalid cert"
|
||||
msgstr ""
|
||||
|
||||
#: py/compile.c
|
||||
msgid "invalid decorator"
|
||||
msgstr ""
|
||||
@ -3233,10 +3229,6 @@ msgstr ""
|
||||
msgid "invalid hostname"
|
||||
msgstr ""
|
||||
|
||||
#: extmod/modussl_axtls.c
|
||||
msgid "invalid key"
|
||||
msgstr ""
|
||||
|
||||
#: py/compile.c
|
||||
msgid "invalid micropython decorator"
|
||||
msgstr ""
|
||||
|
@ -13,6 +13,8 @@ override undefine MICROPY_FORCE_32BIT
|
||||
override undefine CROSS_COMPILE
|
||||
override undefine FROZEN_DIR
|
||||
override undefine FROZEN_MPY_DIR
|
||||
override undefine USER_C_MODULES
|
||||
override undefine SRC_MOD
|
||||
override undefine BUILD
|
||||
override undefine PROG
|
||||
endif
|
||||
|
@ -122,9 +122,6 @@ void gc_collect(void) {
|
||||
// GC stack (and regs because we captured them)
|
||||
void **regs_ptr = (void **)(void *)®s;
|
||||
gc_collect_root(regs_ptr, ((mp_uint_t)MP_STATE_THREAD(stack_top) - (mp_uint_t)®s) / sizeof(mp_uint_t));
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
mp_unix_mark_exec();
|
||||
#endif
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#ifdef _WIN32
|
||||
#include "fmode.h"
|
||||
#endif
|
||||
@ -46,9 +47,7 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
|
||||
}
|
||||
|
||||
#if MICROPY_PY___FILE__
|
||||
if (input_kind == MP_PARSE_FILE_INPUT) {
|
||||
mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
|
||||
}
|
||||
mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
|
||||
#endif
|
||||
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
|
||||
@ -77,20 +76,22 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
|
||||
|
||||
STATIC int usage(char **argv) {
|
||||
printf(
|
||||
"usage: %s [<opts>] [-X <implopt>] <input filename>\n"
|
||||
"Options:\n"
|
||||
"-o : output file for compiled bytecode (defaults to input with .mpy extension)\n"
|
||||
"-s : source filename to embed in the compiled bytecode (defaults to input file)\n"
|
||||
"-v : verbose (trace various operations); can be multiple\n"
|
||||
"-O[N] : apply bytecode optimizations of level N\n"
|
||||
"\n"
|
||||
"Target specific options:\n"
|
||||
"-msmall-int-bits=number : set the maximum bits used to encode a small-int\n"
|
||||
"-mno-unicode : don't support unicode in compiled strings\n"
|
||||
"-mcache-lookup-bc : cache map lookups in the bytecode\n"
|
||||
"\n"
|
||||
"Implementation specific options:\n", argv[0]
|
||||
);
|
||||
"usage: %s [<opts>] [-X <implopt>] <input filename>\n"
|
||||
"Options:\n"
|
||||
"--version : show version information\n"
|
||||
"-o : output file for compiled bytecode (defaults to input with .mpy extension)\n"
|
||||
"-s : source filename to embed in the compiled bytecode (defaults to input file)\n"
|
||||
"-v : verbose (trace various operations); can be multiple\n"
|
||||
"-O[N] : apply bytecode optimizations of level N\n"
|
||||
"\n"
|
||||
"Target specific options:\n"
|
||||
"-msmall-int-bits=number : set the maximum bits used to encode a small-int\n"
|
||||
"-mno-unicode : don't support unicode in compiled strings\n"
|
||||
"-mcache-lookup-bc : cache map lookups in the bytecode\n"
|
||||
"-march=<arch> : set architecture for native emitter; x86, x64, armv6, armv7m, xtensa\n"
|
||||
"\n"
|
||||
"Implementation specific options:\n", argv[0]
|
||||
);
|
||||
int impl_opts_cnt = 0;
|
||||
printf(
|
||||
" emit={bytecode,native,viper} -- set the default code emitter\n"
|
||||
@ -172,6 +173,15 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
mp_dynamic_compiler.small_int_bits = 31;
|
||||
mp_dynamic_compiler.opt_cache_map_lookup_in_bytecode = 0;
|
||||
mp_dynamic_compiler.py_builtins_str_unicode = 1;
|
||||
#if defined(__i386__)
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86;
|
||||
#elif defined(__x86_64__)
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X64;
|
||||
#elif defined(__arm__) && !defined(__thumb2__)
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6;
|
||||
#else
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_NONE;
|
||||
#endif
|
||||
|
||||
const char *input_file = NULL;
|
||||
const char *output_file = NULL;
|
||||
@ -182,6 +192,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
if (argv[a][0] == '-') {
|
||||
if (strcmp(argv[a], "-X") == 0) {
|
||||
a += 1;
|
||||
} else if (strcmp(argv[a], "--version") == 0) {
|
||||
printf("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE
|
||||
"; mpy-cross emitting mpy v" MP_STRINGIFY(MPY_VERSION) "\n");
|
||||
return 0;
|
||||
} else if (strcmp(argv[a], "-v") == 0) {
|
||||
mp_verbose_flag++;
|
||||
} else if (strncmp(argv[a], "-O", 2) == 0) {
|
||||
@ -220,6 +234,21 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
mp_dynamic_compiler.py_builtins_str_unicode = 0;
|
||||
} else if (strcmp(argv[a], "-municode") == 0) {
|
||||
mp_dynamic_compiler.py_builtins_str_unicode = 1;
|
||||
} else if (strncmp(argv[a], "-march=", sizeof("-march=") - 1) == 0) {
|
||||
const char *arch = argv[a] + sizeof("-march=") - 1;
|
||||
if (strcmp(arch, "x86") == 0) {
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86;
|
||||
} else if (strcmp(arch, "x64") == 0) {
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X64;
|
||||
} else if (strcmp(arch, "armv6") == 0) {
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6;
|
||||
} else if (strcmp(arch, "armv7m") == 0) {
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV7M;
|
||||
} else if (strcmp(arch, "xtensa") == 0) {
|
||||
mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_XTENSA;
|
||||
} else {
|
||||
return usage(argv);
|
||||
}
|
||||
} else {
|
||||
return usage(argv);
|
||||
}
|
||||
|
@ -9,13 +9,15 @@
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (0)
|
||||
#define MICROPY_PERSISTENT_CODE_SAVE (1)
|
||||
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_X86 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB_ARMV7M (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB_FLOAT (0)
|
||||
#define MICROPY_EMIT_ARM (0)
|
||||
#define MICROPY_EMIT_X64 (1)
|
||||
#define MICROPY_EMIT_X86 (1)
|
||||
#define MICROPY_EMIT_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB_ARMV7M (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB_FLOAT (1)
|
||||
#define MICROPY_EMIT_ARM (1)
|
||||
#define MICROPY_EMIT_XTENSA (1)
|
||||
#define MICROPY_EMIT_INLINE_XTENSA (1)
|
||||
|
||||
#define MICROPY_DYNAMIC_COMPILER (1)
|
||||
#define MICROPY_COMP_CONST_FOLDING (1)
|
||||
@ -134,10 +136,6 @@ typedef long mp_off_t;
|
||||
|
||||
#define MP_PLAT_PRINT_STRN(str, len) (void)0
|
||||
|
||||
#ifndef MP_NOINLINE
|
||||
#define MP_NOINLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#ifdef __FreeBSD__
|
||||
#include <stdlib.h>
|
||||
|
@ -302,18 +302,7 @@ SRC_C += \
|
||||
eic_handler.c \
|
||||
fatfs_port.c \
|
||||
freetouch/adafruit_ptc.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
mphalport.c \
|
||||
peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/adc.c \
|
||||
peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/cache.c \
|
||||
@ -331,7 +320,6 @@ SRC_C += \
|
||||
peripherals/samd/sercom.c \
|
||||
peripherals/samd/timers.c \
|
||||
reset.c \
|
||||
supervisor/shared/memory.c \
|
||||
timer_handler.c \
|
||||
|
||||
ifeq ($(CIRCUITPY_SDIOIO),1)
|
||||
@ -390,6 +378,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -12,28 +12,16 @@ LONGINT_IMPL = MPZ
|
||||
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
# supersized, not ultra-supersized
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
CFLAGS_INLINE_LIMIT = 60
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
||||
CFLAGS_BOARD = --param max-inline-insns-auto=15
|
||||
ifeq ($(TRANSLATION), ja)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
endif
|
||||
ifeq ($(TRANSLATION), zh_Latn_pinyin)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
endif
|
||||
ifeq ($(TRANSLATION), de_DE)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
SUPEROPT_VM = 0
|
||||
endif
|
||||
|
@ -17,6 +17,7 @@ CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
|
@ -19,6 +19,7 @@ CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
# too itsy bitsy for all of displayio
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
|
@ -17,6 +17,7 @@ CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
@ -21,6 +21,7 @@ CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_PS2IO = 0
|
||||
CIRCUITPY_PULSEIO = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
CIRCUITPY_SAMD = 0
|
||||
|
@ -18,6 +18,7 @@ CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
@ -12,9 +12,10 @@ LONGINT_IMPL = NONE
|
||||
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
@ -13,8 +13,9 @@ LONGINT_IMPL = MPZ
|
||||
CIRCUITPY_AUDIOIO = 0
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
CIRCUITPY_BITMAPTOOLS = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar
|
||||
|
||||
|
@ -19,6 +19,7 @@ CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
@ -20,18 +20,8 @@ CIRCUITPY_I2CPERIPHERAL = 0
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
SUPEROPT_VM = 0
|
||||
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
|
||||
CFLAGS_BOARD = --param max-inline-insns-auto=15
|
||||
ifeq ($(TRANSLATION), zh_Latn_pinyin)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
endif
|
||||
ifeq ($(TRANSLATION), ja)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
endif
|
||||
ifeq ($(TRANSLATION), de_DE)
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
CFLAGS_INLINE_LIMIT = 35
|
||||
SUPEROPT_VM = 0
|
||||
endif
|
||||
|
@ -168,18 +168,6 @@ SRC_C += \
|
||||
mphalport.c \
|
||||
boards/$(BOARD)/board.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
supervisor/shared/memory.c \
|
||||
lib/tinyusb/src/portable/sony/cxd56/dcd_cxd56.c \
|
||||
|
||||
OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
@ -189,6 +177,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
# List of sources for qstr extraction
|
||||
|
@ -182,24 +182,12 @@ SRC_C += \
|
||||
boards/$(BOARD)/board.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
modules/$(CIRCUITPY_MODULE).c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
lib/netutils/netutils.c \
|
||||
peripherals/timer.c \
|
||||
peripherals/touch.c \
|
||||
peripherals/pcnt.c \
|
||||
peripherals/pins.c \
|
||||
peripherals/rmt.c \
|
||||
supervisor/shared/memory.c
|
||||
peripherals/rmt.c
|
||||
|
||||
ifneq ($(USB),FALSE)
|
||||
SRC_C += lib/tinyusb/src/portable/espressif/esp32s2/dcd_esp32s2.c
|
||||
@ -227,6 +215,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -104,7 +104,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
||||
// First, check to see if we match any given alarms.
|
||||
uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status;
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
continue;
|
||||
}
|
||||
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
@ -179,7 +179,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
// TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms.
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
continue;
|
||||
}
|
||||
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
|
@ -45,7 +45,7 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala
|
||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// First, check to see if we match
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
|
||||
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
|
||||
alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
|
||||
if (!mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
||||
continue;
|
||||
}
|
||||
if (timealarm_set) {
|
||||
|
@ -45,7 +45,7 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s
|
||||
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// First, check to see if we match any given alarms.
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) {
|
||||
if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar
|
||||
alarm_touch_touchalarm_obj_t *touch_alarm = MP_OBJ_NULL;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_touch_touchalarm_type)) {
|
||||
if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) {
|
||||
if (deep_sleep && touch_alarm_set) {
|
||||
mp_raise_ValueError(translate("Only one TouchAlarm can be set in deep sleep."));
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ void wifi_reset(void) {
|
||||
}
|
||||
|
||||
void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address) {
|
||||
if (!MP_OBJ_IS_TYPE(ip_address, &ipaddress_ipv4address_type)) {
|
||||
if (!mp_obj_is_type(ip_address, &ipaddress_ipv4address_type)) {
|
||||
mp_raise_ValueError(translate("Only IPv4 addresses supported"));
|
||||
}
|
||||
mp_obj_t packed = common_hal_ipaddress_ipv4address_get_packed(ip_address);
|
||||
|
@ -122,19 +122,7 @@ SRC_C += \
|
||||
fatfs_port.c \
|
||||
mphalport.c \
|
||||
boards/$(BOARD)/board.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
supervisor/shared/memory.c
|
||||
boards/$(BOARD)/pins.c
|
||||
|
||||
ifneq ($(USB),FALSE)
|
||||
SRC_C += lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c
|
||||
@ -163,6 +151,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -154,24 +154,13 @@ SRC_C += \
|
||||
boards/$(BOARD)/flash_config.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
fatfs_port.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c \
|
||||
mphalport.c \
|
||||
peripherals/mimxrt10xx/$(CHIP_FAMILY)/clocks.c \
|
||||
peripherals/mimxrt10xx/$(CHIP_FAMILY)/periph.c \
|
||||
peripherals/mimxrt10xx/$(CHIP_FAMILY)/pins.c \
|
||||
reset.c \
|
||||
supervisor/flexspi_nor_flash_ops.c \
|
||||
supervisor/shared/memory.c
|
||||
supervisor/flexspi_nor_flash_ops.c
|
||||
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
@ -224,6 +213,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -156,17 +156,6 @@ SRC_C += \
|
||||
device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \
|
||||
bluetooth/ble_drv.c \
|
||||
common-hal/_bleio/bonding.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
nrfx/mdk/system_$(MCU_SUB_VARIANT).c \
|
||||
peripherals/nrf/cache.c \
|
||||
peripherals/nrf/clocks.c \
|
||||
@ -174,8 +163,7 @@ SRC_C += \
|
||||
peripherals/nrf/$(MCU_CHIP)/power.c \
|
||||
peripherals/nrf/nvm.c \
|
||||
peripherals/nrf/timers.c \
|
||||
sd_mutex.c \
|
||||
supervisor/shared/memory.c
|
||||
sd_mutex.c
|
||||
|
||||
# USB source files for nrf52840
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
@ -235,6 +223,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -27,6 +27,7 @@ CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 1
|
||||
CIRCUITPY_SDCARDIO = 0
|
||||
CIRCUITPY_SYNTHIO = 0
|
||||
CIRCUITPY_TOUCHIO = 0
|
||||
CIRCUITPY_ULAB = 0
|
||||
CIRCUITPY_USB_CDC = 0
|
||||
|
@ -645,7 +645,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
|
||||
mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
|
||||
mp_obj_t uuid_obj;
|
||||
while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
|
||||
if (!mp_obj_is_type(uuid_obj, &bleio_uuid_type)) {
|
||||
mp_raise_TypeError(translate("non-UUID found in service_uuids_whitelist"));
|
||||
}
|
||||
bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
|
||||
|
@ -199,21 +199,9 @@ SRC_C += \
|
||||
peripherals/pins.c \
|
||||
extmod/crypto-algorithms/sha256.c \
|
||||
fatfs_port.c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c \
|
||||
lib/tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
mphalport.c \
|
||||
supervisor/shared/memory.c \
|
||||
|
||||
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
@ -248,6 +236,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
@ -599,7 +599,7 @@ const mp_obj_type_t rp2pio_statemachine_type = {
|
||||
};
|
||||
|
||||
rp2pio_statemachine_obj_t *validate_obj_is_statemachine(mp_obj_t obj) {
|
||||
if (!MP_OBJ_IS_TYPE(obj, &rp2pio_statemachine_type)) {
|
||||
if (!mp_obj_is_type(obj, &rp2pio_statemachine_type)) {
|
||||
mp_raise_TypeError_varg(translate("Expected a %q"), rp2pio_statemachine_type.name);
|
||||
}
|
||||
return MP_OBJ_TO_PTR(obj);
|
||||
|
@ -117,7 +117,7 @@ MCU_FLAGS_H7 = -mcpu=cortex-m7
|
||||
CFLAGS += $(MCU_FLAGS_$(MCU_SERIES))
|
||||
|
||||
# Select HAL file for distribution via mpconfigport
|
||||
CFLAGS += -DSTM32_HAL_H='<stm32$(MCU_SERIES_LOWER)xx_hal.h>'
|
||||
CFLAGS += -DSTM32_HAL_H="<stm32$(MCU_SERIES_LOWER)xx_hal.h>"
|
||||
|
||||
CFLAGS += -DSTM32_SERIES_LOWER='"stm32$(MCU_SERIES_LOWER)"'
|
||||
|
||||
@ -224,19 +224,7 @@ SRC_C += \
|
||||
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/pins.c \
|
||||
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/gpio.c \
|
||||
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/periph.c \
|
||||
packages/$(MCU_PACKAGE).c \
|
||||
lib/libc/string0.c \
|
||||
lib/mp-readline/readline.c \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/ccsbcs.c \
|
||||
lib/timeutils/timeutils.c \
|
||||
lib/utils/buffer_helper.c \
|
||||
lib/utils/context_manager_helpers.c \
|
||||
lib/utils/interrupt_char.c \
|
||||
lib/utils/pyexec.c \
|
||||
lib/utils/stdout_helpers.c \
|
||||
lib/utils/sys_stdio_mphal.c \
|
||||
supervisor/shared/memory.c
|
||||
packages/$(MCU_PACKAGE).c
|
||||
|
||||
ifneq ($(USB),FALSE)
|
||||
SRC_C += lib/tinyusb/src/portable/st/synopsys/dcd_synopsys.c
|
||||
@ -267,6 +255,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
ifeq ($(INTERNAL_LIBM),1)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o))
|
||||
endif
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
|
||||
|
||||
|
@ -166,7 +166,7 @@ LIB_SRC_C = $(addprefix lib/,\
|
||||
# FatFS VFS support
|
||||
LIB_SRC_C += $(addprefix lib/,\
|
||||
oofatfs/ff.c \
|
||||
oofatfs/option/unicode.c \
|
||||
oofatfs/ffunicode.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O)
|
||||
@ -259,10 +259,11 @@ coverage:
|
||||
|
||||
coverage_test: coverage
|
||||
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 -d thread
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --emit native
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -j1 --via-mpy -d basics float
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests -d thread
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --emit native
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy -d basics float micropython
|
||||
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/micropython_coverage ./run-tests --via-mpy --emit native -d basics float micropython
|
||||
cat $(TOP)/tests/basics/0prelim.py | ./micropython_coverage | grep -q 'abc'
|
||||
gcov -o build-coverage/py $(TOP)/py/*.c
|
||||
gcov -o build-coverage/extmod $(TOP)/extmod/*.c
|
||||
|
@ -163,6 +163,7 @@ STATIC mp_obj_t extra_coverage(void) {
|
||||
mp_printf(&mp_plat_print, "%x\n", 0x80000000); // should print unsigned
|
||||
mp_printf(&mp_plat_print, "%X\n", 0x80000000); // should print unsigned
|
||||
mp_printf(&mp_plat_print, "abc\n%"); // string ends in middle of format specifier
|
||||
mp_printf(&mp_plat_print, "%%\n"); // literal % character
|
||||
}
|
||||
|
||||
// GC
|
||||
@ -252,7 +253,7 @@ STATIC mp_obj_t extra_coverage(void) {
|
||||
mp_printf(&mp_plat_print, "# str\n");
|
||||
|
||||
// intern string
|
||||
mp_printf(&mp_plat_print, "%d\n", MP_OBJ_IS_QSTR(mp_obj_str_intern(mp_obj_new_str("intern me", 9))));
|
||||
mp_printf(&mp_plat_print, "%d\n", mp_obj_is_qstr(mp_obj_str_intern(mp_obj_new_str("intern me", 9))));
|
||||
}
|
||||
|
||||
// bytearray
|
||||
|
@ -193,7 +193,7 @@ STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
|
||||
|
||||
mp_obj_t fid = args[0].u_obj;
|
||||
|
||||
if (MP_OBJ_IS_SMALL_INT(fid)) {
|
||||
if (mp_obj_is_small_int(fid)) {
|
||||
o->fd = MP_OBJ_SMALL_INT_VALUE(fid);
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
@ -149,9 +149,14 @@ STATIC void gc_helper_get_regs(regs_t arr) {
|
||||
#endif // MICROPY_GCREGS_SETJMP
|
||||
|
||||
// this function is used by mpthreadport.c
|
||||
void gc_collect_regs_and_stack(void);
|
||||
MP_NOINLINE void gc_collect_regs_and_stack(void);
|
||||
|
||||
void gc_collect_regs_and_stack(void) {
|
||||
// Explicitly mark this as noinline to make sure the regs variable
|
||||
// is effectively at the top of the stack: otherwise, in builds where
|
||||
// LTO is enabled and a lot of inlining takes place we risk a stack
|
||||
// layout where regs is lower on the stack than pointers which have
|
||||
// just been allocated but not yet marked, and get incorrectly sweeped.
|
||||
MP_NOINLINE void gc_collect_regs_and_stack(void) {
|
||||
regs_t regs;
|
||||
gc_helper_get_regs(regs);
|
||||
// GC stack (and regs because we captured them)
|
||||
|
@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-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
|
||||
@ -653,6 +654,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_THREAD
|
||||
mp_thread_deinit();
|
||||
#endif
|
||||
|
||||
#if defined(MICROPY_UNIX_COVERAGE)
|
||||
gc_sweep_all();
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: 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
|
||||
@ -141,7 +141,7 @@ STATIC ffi_type *char2ffi_type(char c) {
|
||||
}
|
||||
|
||||
STATIC ffi_type *get_ffi_type(mp_obj_t o_in) {
|
||||
if (MP_OBJ_IS_STR(o_in)) {
|
||||
if (mp_obj_is_str(o_in)) {
|
||||
const char *s = mp_obj_str_get_str(o_in);
|
||||
ffi_type *t = char2ffi_type(*s);
|
||||
if (t != NULL) {
|
||||
@ -365,6 +365,7 @@ STATIC void ffifunc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
|
||||
}
|
||||
|
||||
STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
(void)n_kw;
|
||||
mp_obj_ffifunc_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
assert(n_kw == 0);
|
||||
assert(n_args == self->cif.nargs);
|
||||
@ -386,9 +387,9 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
||||
#endif
|
||||
} else if (a == mp_const_none) {
|
||||
values[i] = 0;
|
||||
} else if (MP_OBJ_IS_INT(a)) {
|
||||
} else if (mp_obj_is_int(a)) {
|
||||
values[i] = mp_obj_int_get_truncated(a);
|
||||
} else if (MP_OBJ_IS_STR(a)) {
|
||||
} else if (mp_obj_is_str(a)) {
|
||||
const char *s = mp_obj_str_get_str(a);
|
||||
values[i] = (ffi_arg)(intptr_t)s;
|
||||
} else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) {
|
||||
@ -399,7 +400,7 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
|
||||
goto error;
|
||||
}
|
||||
values[i] = (ffi_arg)(intptr_t)bufinfo.buf;
|
||||
} else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) {
|
||||
} else if (mp_obj_is_type(a, &fficallback_type)) {
|
||||
mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
|
||||
values[i] = (ffi_arg)(intptr_t)p->func;
|
||||
} else {
|
||||
|
@ -658,12 +658,12 @@ STATIC mp_obj_t mod_jni_array(mp_obj_t type_in, mp_obj_t size_in) {
|
||||
mp_int_t size = mp_obj_get_int(size_in);
|
||||
jobject res = NULL;
|
||||
|
||||
if (MP_OBJ_IS_TYPE(type_in, &jclass_type)) {
|
||||
if (mp_obj_is_type(type_in, &jclass_type)) {
|
||||
|
||||
mp_obj_jclass_t *jcls = MP_OBJ_TO_PTR(type_in);
|
||||
res = JJ(NewObjectArray, size, jcls->cls, NULL);
|
||||
|
||||
} else if (MP_OBJ_IS_STR(type_in)) {
|
||||
} else if (mp_obj_is_str(type_in)) {
|
||||
const char *type = mp_obj_str_get_str(type_in);
|
||||
switch (*type) {
|
||||
case 'Z':
|
||||
|
@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015 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
|
||||
@ -59,10 +60,11 @@ uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) {
|
||||
static uintptr_t last_base = (uintptr_t)-1;
|
||||
static uintptr_t map_page;
|
||||
if (!fd) {
|
||||
fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||||
if (fd == -1) {
|
||||
int _fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||||
if (_fd == -1) {
|
||||
mp_raise_OSError(errno);
|
||||
}
|
||||
fd = _fd;
|
||||
}
|
||||
|
||||
uintptr_t cur_base = addr & ~MICROPY_PAGE_MASK;
|
||||
|
@ -3,8 +3,8 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-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
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* Copyright (c) 2014-2015 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
|
||||
@ -77,7 +77,7 @@ STATIC mp_obj_t mod_termios_tcsetattr(mp_obj_t fd_in, mp_obj_t when_in, mp_obj_t
|
||||
when = TCSANOW;
|
||||
}
|
||||
|
||||
assert(MP_OBJ_IS_TYPE(attrs_in, &mp_type_list));
|
||||
assert(mp_obj_is_type(attrs_in, &mp_type_list));
|
||||
mp_obj_list_t *attrs = MP_OBJ_TO_PTR(attrs_in);
|
||||
|
||||
term.c_iflag = mp_obj_get_int(attrs->items[0]);
|
||||
|
@ -3,7 +3,8 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-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
|
||||
|
@ -66,7 +66,7 @@ typedef struct _mp_obj_poll_t {
|
||||
} mp_obj_poll_t;
|
||||
|
||||
STATIC int get_fd(mp_obj_t fdlike) {
|
||||
if (MP_OBJ_IS_OBJ(fdlike)) {
|
||||
if (mp_obj_is_obj(fdlike)) {
|
||||
const mp_stream_p_t *stream_p = mp_get_stream_raise(fdlike, MP_STREAM_OP_IOCTL);
|
||||
int err;
|
||||
mp_uint_t res = stream_p->ioctl(fdlike, MP_STREAM_GET_FILENO, 0, &err);
|
||||
@ -80,7 +80,7 @@ STATIC int get_fd(mp_obj_t fdlike) {
|
||||
/// \method register(obj[, eventmask])
|
||||
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
bool is_fd = MP_OBJ_IS_INT(args[1]);
|
||||
bool is_fd = mp_obj_is_int(args[1]);
|
||||
int fd = get_fd(args[1]);
|
||||
|
||||
mp_uint_t flags;
|
||||
|
@ -3,8 +3,8 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky
|
||||
* SPDX-FileCopyrightText: 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
|
||||
@ -162,7 +162,12 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ);
|
||||
int r = connect(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len);
|
||||
RAISE_ERRNO(r, errno);
|
||||
int err = errno;
|
||||
if (r == -1 && self->blocking && err == EINPROGRESS) {
|
||||
// EINPROGRESS on a blocking socket means the operation timed out
|
||||
err = MP_ETIMEDOUT;
|
||||
}
|
||||
RAISE_ERRNO(r, err);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
||||
@ -192,7 +197,12 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
byte addr[32];
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
int fd = accept(self->fd, (struct sockaddr *)&addr, &addr_len);
|
||||
RAISE_ERRNO(fd, errno);
|
||||
int err = errno;
|
||||
if (fd == -1 && self->blocking && err == EAGAIN) {
|
||||
// EAGAIN on a blocking socket means the operation timed out
|
||||
err = MP_ETIMEDOUT;
|
||||
}
|
||||
RAISE_ERRNO(fd, err);
|
||||
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
t->items[0] = MP_OBJ_FROM_PTR(socket_new(fd));
|
||||
@ -301,7 +311,7 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
||||
const void *optval;
|
||||
socklen_t optlen;
|
||||
int val;
|
||||
if (MP_OBJ_IS_INT(args[3])) {
|
||||
if (mp_obj_is_int(args[3])) {
|
||||
val = mp_obj_int_get_truncated(args[3]);
|
||||
optval = &val;
|
||||
optlen = sizeof(val);
|
||||
@ -339,10 +349,9 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
||||
struct timeval tv = {0,};
|
||||
bool new_blocking = true;
|
||||
|
||||
if (timeout_in == mp_const_none) {
|
||||
setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, NULL, 0);
|
||||
setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, NULL, 0);
|
||||
} else {
|
||||
// Timeout of None means no timeout, which in POSIX is signified with 0 timeout,
|
||||
// and that's how 'tv' is initialized above
|
||||
if (timeout_in != mp_const_none) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_float_t val = mp_obj_get_float(timeout_in);
|
||||
double ipart;
|
||||
@ -356,14 +365,17 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
||||
// for Python API it means non-blocking.
|
||||
if (tv.tv_sec == 0 && tv.tv_usec == 0) {
|
||||
new_blocking = false;
|
||||
} else {
|
||||
setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO,
|
||||
&tv, sizeof(struct timeval));
|
||||
setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO,
|
||||
&tv, sizeof(struct timeval));
|
||||
}
|
||||
}
|
||||
|
||||
if (new_blocking) {
|
||||
int r;
|
||||
r = setsockopt(self->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
|
||||
RAISE_ERRNO(r, errno);
|
||||
r = setsockopt(self->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
|
||||
RAISE_ERRNO(r, errno);
|
||||
}
|
||||
|
||||
if (self->blocking != new_blocking) {
|
||||
socket_setblocking(self_in, mp_obj_new_bool(new_blocking));
|
||||
}
|
||||
@ -393,13 +405,13 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, con
|
||||
int proto = 0;
|
||||
|
||||
if (n_args > 0) {
|
||||
assert(MP_OBJ_IS_SMALL_INT(args[0]));
|
||||
assert(mp_obj_is_small_int(args[0]));
|
||||
family = MP_OBJ_SMALL_INT_VALUE(args[0]);
|
||||
if (n_args > 1) {
|
||||
assert(MP_OBJ_IS_SMALL_INT(args[1]));
|
||||
assert(mp_obj_is_small_int(args[1]));
|
||||
type = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||
if (n_args > 2) {
|
||||
assert(MP_OBJ_IS_SMALL_INT(args[2]));
|
||||
assert(mp_obj_is_small_int(args[2]));
|
||||
proto = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||
}
|
||||
}
|
||||
@ -497,7 +509,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(size_t n_args, const mp_obj_t *args) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
// getaddrinfo accepts port in string notation, so however
|
||||
// it may seem stupid, we need to convert int to str
|
||||
if (MP_OBJ_IS_SMALL_INT(args[1])) {
|
||||
if (mp_obj_is_small_int(args[1])) {
|
||||
unsigned port = (unsigned short)MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||
snprintf(buf, sizeof(buf), "%u", port);
|
||||
serv = buf;
|
||||
|
@ -135,7 +135,7 @@
|
||||
#ifndef MICROPY_PY_USELECT_POSIX
|
||||
#define MICROPY_PY_USELECT_POSIX (1)
|
||||
#endif
|
||||
#define MICROPY_PY_WEBSOCKET (0)
|
||||
#define MICROPY_PY_UWEBSOCKET (0)
|
||||
#define MICROPY_PY_MACHINE (0)
|
||||
#define MICROPY_PY_MACHINE_PULSE (0)
|
||||
#define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr
|
||||
@ -144,7 +144,7 @@
|
||||
#define MICROPY_FATFS_ENABLE_LFN (1)
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#define MICROPY_FATFS_MAX_SS (4096)
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_VFS_FAT (0)
|
||||
|
||||
// Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc.
|
||||
|
@ -36,9 +36,12 @@
|
||||
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
|
||||
#define MICROPY_ENABLE_SCHEDULER (1)
|
||||
#define MICROPY_READER_VFS (1)
|
||||
#define MICROPY_WARNINGS_CATEGORY (1)
|
||||
#define MICROPY_MODULE_GETATTR (1)
|
||||
#define MICROPY_PY_DELATTR_SETATTR (1)
|
||||
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW_ITEMSIZE (1)
|
||||
#define MICROPY_PY_BUILTINS_NEXT2 (1)
|
||||
#define MICROPY_PY_BUILTINS_RANGE_BINOP (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
|
||||
@ -58,6 +61,7 @@
|
||||
#define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1)
|
||||
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
|
||||
#define MICROPY_PY_UCRYPTOLIB (1)
|
||||
#define MICROPY_PY_UCRYPTOLIB_CTR (1)
|
||||
|
||||
// TODO these should be generic, not bound to fatfs
|
||||
#define mp_type_fileio mp_type_vfs_posix_fileio
|
||||
|
@ -34,8 +34,10 @@
|
||||
|
||||
#if MICROPY_PY_THREAD
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
// this structure forms a linked list, one node per active thread
|
||||
typedef struct _thread_t {
|
||||
@ -53,7 +55,12 @@ STATIC thread_t *thread;
|
||||
|
||||
// this is used to synchronise the signal handler of the thread
|
||||
// it's needed because we can't use any pthread calls in a signal handler
|
||||
STATIC volatile int thread_signal_done;
|
||||
#if defined(__APPLE__)
|
||||
STATIC char thread_signal_done_name[25];
|
||||
STATIC sem_t *thread_signal_done_p;
|
||||
#else
|
||||
STATIC sem_t thread_signal_done;
|
||||
#endif
|
||||
|
||||
// this signal handler is used to scan the regs and stack of a thread
|
||||
STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) {
|
||||
@ -70,7 +77,11 @@ STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) {
|
||||
void **ptrs = (void **)(void *)MP_STATE_THREAD(pystack_start);
|
||||
gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void *));
|
||||
#endif
|
||||
thread_signal_done = 1;
|
||||
#if defined(__APPLE__)
|
||||
sem_post(thread_signal_done_p);
|
||||
#else
|
||||
sem_post(&thread_signal_done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +96,13 @@ void mp_thread_init(void) {
|
||||
thread->arg = NULL;
|
||||
thread->next = NULL;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
snprintf(thread_signal_done_name, sizeof(thread_signal_done_name), "micropython_sem_%d", (int)thread->id);
|
||||
thread_signal_done_p = sem_open(thread_signal_done_name, O_CREAT | O_EXCL, 0666, 0);
|
||||
#else
|
||||
sem_init(&thread_signal_done, 0, 0);
|
||||
#endif
|
||||
|
||||
// enable signal handler for garbage collection
|
||||
struct sigaction sa;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
@ -93,6 +111,23 @@ void mp_thread_init(void) {
|
||||
sigaction(SIGUSR1, &sa, NULL);
|
||||
}
|
||||
|
||||
void mp_thread_deinit(void) {
|
||||
pthread_mutex_lock(&thread_mutex);
|
||||
while (thread->next != NULL) {
|
||||
thread_t *th = thread;
|
||||
thread = thread->next;
|
||||
pthread_cancel(th->id);
|
||||
free(th);
|
||||
}
|
||||
pthread_mutex_unlock(&thread_mutex);
|
||||
#if defined(__APPLE__)
|
||||
sem_close(thread_signal_done_p);
|
||||
sem_unlink(thread_signal_done_name);
|
||||
#endif
|
||||
assert(thread->id == pthread_self());
|
||||
free(thread);
|
||||
}
|
||||
|
||||
// This function scans all pointers that are external to the current thread.
|
||||
// It does this by signalling all other threads and getting them to scan their
|
||||
// own registers and stack. Note that there may still be some edge cases left
|
||||
@ -109,11 +144,12 @@ void mp_thread_gc_others(void) {
|
||||
if (!th->ready) {
|
||||
continue;
|
||||
}
|
||||
thread_signal_done = 0;
|
||||
pthread_kill(th->id, SIGUSR1);
|
||||
while (thread_signal_done == 0) {
|
||||
sched_yield();
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
sem_wait(thread_signal_done_p);
|
||||
#else
|
||||
sem_wait(&thread_signal_done);
|
||||
#endif
|
||||
}
|
||||
pthread_mutex_unlock(&thread_mutex);
|
||||
}
|
||||
@ -127,6 +163,7 @@ void mp_thread_set_state(void *state) {
|
||||
}
|
||||
|
||||
void mp_thread_start(void) {
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
pthread_mutex_lock(&thread_mutex);
|
||||
for (thread_t *th = thread; th != NULL; th = th->next) {
|
||||
if (th->id == pthread_self()) {
|
||||
@ -159,6 +196,11 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
|
||||
goto er;
|
||||
}
|
||||
|
||||
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
if (ret != 0) {
|
||||
goto er;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&thread_mutex);
|
||||
|
||||
// create thread
|
||||
@ -191,12 +233,18 @@ er:
|
||||
|
||||
void mp_thread_finish(void) {
|
||||
pthread_mutex_lock(&thread_mutex);
|
||||
// TODO unlink from list
|
||||
thread_t *prev = NULL;
|
||||
for (thread_t *th = thread; th != NULL; th = th->next) {
|
||||
if (th->id == pthread_self()) {
|
||||
th->ready = 0;
|
||||
if (prev == NULL) {
|
||||
thread = th->next;
|
||||
} else {
|
||||
prev->next = th->next;
|
||||
}
|
||||
free(th);
|
||||
break;
|
||||
}
|
||||
prev = th;
|
||||
}
|
||||
pthread_mutex_unlock(&thread_mutex);
|
||||
}
|
||||
|
@ -29,4 +29,5 @@
|
||||
typedef pthread_mutex_t mp_thread_mutex_t;
|
||||
|
||||
void mp_thread_init(void);
|
||||
void mp_thread_deinit(void);
|
||||
void mp_thread_gc_others(void);
|
||||
|
16
py/asmarm.c
16
py/asmarm.c
@ -197,7 +197,16 @@ void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src) {
|
||||
emit_al(as, asm_arm_op_mov_reg(reg_dest, reg_src));
|
||||
}
|
||||
|
||||
void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) {
|
||||
size_t asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) {
|
||||
// Insert immediate into code and jump over it
|
||||
emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc]
|
||||
emit_al(as, 0xa000000); // b pc
|
||||
size_t loc = mp_asm_base_get_code_pos(&as->base);
|
||||
emit(as, imm);
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_arm_mov_reg_i32_optimised(asm_arm_t *as, uint rd, int imm) {
|
||||
// TODO: There are more variants of immediate values
|
||||
if ((imm & 0xFF) == imm) {
|
||||
emit_al(as, asm_arm_op_mov_imm(rd, imm));
|
||||
@ -205,10 +214,7 @@ void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm) {
|
||||
// mvn is "move not", not "move negative"
|
||||
emit_al(as, asm_arm_op_mvn_imm(rd, ~imm));
|
||||
} else {
|
||||
// Insert immediate into code and jump over it
|
||||
emit_al(as, 0x59f0000 | (rd << 12)); // ldr rd, [pc]
|
||||
emit_al(as, 0xa000000); // b pc
|
||||
emit(as, imm);
|
||||
asm_arm_mov_reg_i32(as, rd, imm);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,8 @@ void asm_arm_bkpt(asm_arm_t *as);
|
||||
|
||||
// mov
|
||||
void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src);
|
||||
void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm);
|
||||
size_t asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm);
|
||||
void asm_arm_mov_reg_i32_optimised(asm_arm_t *as, uint rd, int imm);
|
||||
void asm_arm_mov_local_reg(asm_arm_t *as, int local_num, uint rd);
|
||||
void asm_arm_mov_reg_local(asm_arm_t *as, uint rd, int local_num);
|
||||
void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond);
|
||||
@ -177,7 +178,9 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src);
|
||||
#define ASM_CALL_IND(as, idx) asm_arm_bl_ind(as, idx, ASM_ARM_REG_R3)
|
||||
|
||||
#define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_arm_mov_local_reg((as), (local_num), (reg_src))
|
||||
#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_arm_mov_reg_i32_optimised((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_arm_mov_reg_i32((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_arm_mov_reg_local((as), (reg_dest), (local_num))
|
||||
#define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_arm_mov_reg_reg((as), (reg_dest), (reg_src))
|
||||
#define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_arm_mov_reg_local_addr((as), (reg_dest), (local_num))
|
||||
|
@ -33,6 +33,8 @@
|
||||
// wrapper around everything in this file
|
||||
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/persistentcode.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/asmthumb.h"
|
||||
|
||||
@ -118,6 +120,21 @@ STATIC void asm_thumb_write_word32(asm_thumb_t *as, int w32) {
|
||||
void asm_thumb_entry(asm_thumb_t *as, int num_locals) {
|
||||
assert(num_locals >= 0);
|
||||
|
||||
// If this Thumb machine code is run from ARM state then add a prelude
|
||||
// to switch to Thumb state for the duration of the function.
|
||||
#if MICROPY_DYNAMIC_COMPILER || MICROPY_EMIT_ARM || (defined(__arm__) && !defined(__thumb2__))
|
||||
#if MICROPY_DYNAMIC_COMPILER
|
||||
if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_ARMV6)
|
||||
#endif
|
||||
{
|
||||
asm_thumb_op32(as, 0x4010, 0xe92d); // push {r4, lr}
|
||||
asm_thumb_op32(as, 0xe009, 0xe28f); // add lr, pc, 8 + 1
|
||||
asm_thumb_op32(as, 0xff3e, 0xe12f); // blx lr
|
||||
asm_thumb_op32(as, 0x4010, 0xe8bd); // pop {r4, lr}
|
||||
asm_thumb_op32(as, 0xff1e, 0xe12f); // bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
// work out what to push and how many extra spaces to reserve on stack
|
||||
// so that we have enough for all locals and it's aligned an 8-byte boundary
|
||||
// we push extra regs (r1, r2, r3) to help do the stack adjustment
|
||||
@ -225,10 +242,12 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
|
||||
}
|
||||
|
||||
// if loading lo half with movw, the i16 value will be zero extended into the r32 register!
|
||||
void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) {
|
||||
size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) {
|
||||
assert(reg_dest < ASM_THUMB_REG_R15);
|
||||
size_t loc = mp_asm_base_get_code_pos(&as->base);
|
||||
// mov[wt] reg_dest, #i16_src
|
||||
asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff));
|
||||
return loc;
|
||||
}
|
||||
|
||||
#define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
|
||||
@ -271,12 +290,16 @@ bool asm_thumb_bl_label(asm_thumb_t *as, uint label) {
|
||||
return as->base.pass != MP_ASM_PASS_EMIT || SIGNED_FIT23(rel);
|
||||
}
|
||||
|
||||
void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) {
|
||||
size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) {
|
||||
// movw, movt does it in 8 bytes
|
||||
// ldr [pc, #], dw does it in 6 bytes, but we might not reach to end of code for dw
|
||||
|
||||
size_t loc = mp_asm_base_get_code_pos(&as->base);
|
||||
|
||||
asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32);
|
||||
asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVT, reg_dest, i32 >> 16);
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
|
||||
|
@ -263,14 +263,14 @@ static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uin
|
||||
#define ASM_THUMB_OP_MOVT (0xf2c0)
|
||||
|
||||
void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src);
|
||||
void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src);
|
||||
size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src);
|
||||
|
||||
// these return true if the destination is in range, false otherwise
|
||||
bool asm_thumb_b_n_label(asm_thumb_t *as, uint label);
|
||||
bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide);
|
||||
bool asm_thumb_bl_label(asm_thumb_t *as, uint label);
|
||||
|
||||
void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32_src); // convenience
|
||||
size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32_src); // convenience
|
||||
void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience
|
||||
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience
|
||||
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
|
||||
@ -337,6 +337,8 @@ void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp); // convenien
|
||||
|
||||
#define ASM_MOV_LOCAL_REG(as, local_num, reg) asm_thumb_mov_local_reg((as), (local_num), (reg))
|
||||
#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_thumb_mov_reg_i32_optimised((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_reg_i16((as), ASM_THUMB_OP_MOVW, (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_thumb_mov_reg_i32((as), (reg_dest), (imm))
|
||||
#define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_thumb_mov_reg_local((as), (reg_dest), (local_num))
|
||||
#define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_thumb_mov_reg_reg((as), (reg_dest), (reg_src))
|
||||
#define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_thumb_mov_reg_local_addr((as), (reg_dest), (local_num))
|
||||
|
@ -334,14 +334,16 @@ void asm_x64_mov_i8_to_r8(asm_x64_t *as, int src_i8, int dest_r64) {
|
||||
}
|
||||
*/
|
||||
|
||||
STATIC void asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64) {
|
||||
size_t asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64) {
|
||||
// cpu defaults to i32 to r64, with zero extension
|
||||
if (dest_r64 < 8) {
|
||||
asm_x64_write_byte_1(as, OPCODE_MOV_I64_TO_R64 | dest_r64);
|
||||
} else {
|
||||
asm_x64_write_byte_2(as, REX_PREFIX | REX_B, OPCODE_MOV_I64_TO_R64 | (dest_r64 & 7));
|
||||
}
|
||||
size_t loc = mp_asm_base_get_code_pos(&as->base);
|
||||
asm_x64_write_word32(as, src_i32);
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_x64_mov_i64_to_r64(asm_x64_t *as, int64_t src_i64, int dest_r64) {
|
||||
|
@ -83,6 +83,7 @@ void asm_x64_nop(asm_x64_t *as);
|
||||
void asm_x64_push_r64(asm_x64_t *as, int src_r64);
|
||||
void asm_x64_pop_r64(asm_x64_t *as, int dest_r64);
|
||||
void asm_x64_mov_r64_r64(asm_x64_t *as, int dest_r64, int src_r64);
|
||||
size_t asm_x64_mov_i32_to_r64(asm_x64_t *as, int src_i32, int dest_r64);
|
||||
void asm_x64_mov_i64_to_r64(asm_x64_t *as, int64_t src_i64, int dest_r64);
|
||||
void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64);
|
||||
void asm_x64_mov_r8_to_mem8(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp);
|
||||
@ -181,6 +182,8 @@ void asm_x64_call_ind(asm_x64_t *as, size_t fun_id, int temp_r32);
|
||||
|
||||
#define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_x64_mov_r64_to_local((as), (reg_src), (local_num))
|
||||
#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_x64_mov_i64_to_r64_optimised((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_x64_mov_i32_to_r64((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_x64_mov_i32_to_r64((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_x64_mov_local_to_r64((as), (local_num), (reg_dest))
|
||||
#define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x64_mov_r64_r64((as), (reg_dest), (reg_src))
|
||||
#define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_x64_mov_local_addr_to_r64((as), (local_num), (reg_dest))
|
||||
|
@ -236,9 +236,11 @@ void asm_x86_mov_i8_to_r8(asm_x86_t *as, int src_i8, int dest_r32) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32) {
|
||||
size_t asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32) {
|
||||
asm_x86_write_byte_1(as, OPCODE_MOV_I32_TO_R32 | dest_r32);
|
||||
size_t loc = mp_asm_base_get_code_pos(&as->base);
|
||||
asm_x86_write_word32(as, src_i32);
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_x86_and_r32_r32(asm_x86_t *as, int dest_r32, int src_r32) {
|
||||
|
@ -83,7 +83,7 @@ static inline void asm_x86_end_pass(asm_x86_t *as) {
|
||||
}
|
||||
|
||||
void asm_x86_mov_r32_r32(asm_x86_t *as, int dest_r32, int src_r32);
|
||||
void asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32);
|
||||
size_t asm_x86_mov_i32_to_r32(asm_x86_t *as, int32_t src_i32, int dest_r32);
|
||||
void asm_x86_mov_r8_to_mem8(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
|
||||
void asm_x86_mov_r16_to_mem16(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
|
||||
void asm_x86_mov_r32_to_mem32(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
|
||||
@ -179,6 +179,8 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r
|
||||
|
||||
#define ASM_MOV_LOCAL_REG(as, local_num, reg_src) asm_x86_mov_r32_to_local((as), (reg_src), (local_num))
|
||||
#define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_x86_mov_i32_to_r32((as), (imm), (reg_dest))
|
||||
#define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_x86_mov_local_to_r32((as), (local_num), (reg_dest))
|
||||
#define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_x86_mov_r32_r32((as), (reg_dest), (reg_src))
|
||||
#define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) asm_x86_mov_local_addr_to_r32((as), (local_num), (reg_dest))
|
||||
|
@ -156,18 +156,24 @@ void asm_xtensa_setcc_reg_reg_reg(asm_xtensa_t *as, uint cond, uint reg_dest, ui
|
||||
asm_xtensa_op_movi_n(as, reg_dest, 0);
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
size_t asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
// load the constant
|
||||
uint32_t const_table_offset = (uint8_t *)as->const_table - as->base.code_base;
|
||||
size_t loc = const_table_offset + as->cur_const * WORD_SIZE;
|
||||
asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, loc);
|
||||
// store the constant in the table
|
||||
if (as->const_table != NULL) {
|
||||
as->const_table[as->cur_const] = i32;
|
||||
}
|
||||
++as->cur_const;
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_i32_optimised(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
if (SIGNED_FIT12(i32)) {
|
||||
asm_xtensa_op_movi(as, reg_dest, i32);
|
||||
} else {
|
||||
// load the constant
|
||||
uint32_t const_table_offset = (uint8_t *)as->const_table - as->base.code_base;
|
||||
asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, const_table_offset + as->cur_const * WORD_SIZE);
|
||||
// store the constant in the table
|
||||
if (as->const_table != NULL) {
|
||||
as->const_table[as->cur_const] = i32;
|
||||
}
|
||||
++as->cur_const;
|
||||
asm_xtensa_mov_reg_i32(as, reg_dest, i32);
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user